Report abuse

using FluentNHibernate.Conventions;
using FluentNHibernate.Conventions.AcceptanceCriteria;
using FluentNHibernate.Conventions.Inspections;
using FluentNHibernate.Conventions.Instances;
using Marcusoft.FluentAutomapper.Domain.Conventions;
using FluentNHibernate.Automapping;
using Marcusoft.FluentAutomapper.Domain.Model;
using PrimaryKey = FluentNHibernate.Conventions.Helpers.PrimaryKey;
using ForeignKey = FluentNHibernate.Conventions.Helpers.ForeignKey;
using Table = FluentNHibernate.Conventions.Helpers.Table;
using Inf = Inflector.Net.Inflector;

namespace Marcusoft.FluentAutomapper.Domain
{
    public class FluentNHibernateHelper
    {
        public static AutoPersistenceModel GetAutomappedPeristanceModel()
        {

            return AutoMap.AssemblyOf<Product>()
                .Where(t => t.Namespace.EndsWith("Model") && t.IsAbstract == false)
                .Conventions.Add(
                    PrimaryKey.Name.Is(pk => "ID"),
                    ForeignKey.EndsWith("ID"),
                    Table.Is(t => Inf.Pluralize(t.EntityType.Name)))
                .Conventions.Add<CustomManyToManyTableNameConvention>()
                .Conventions.Add<CustomHasManyConvention>();
        }
    }
}

namespace Marcusoft.FluentAutomapper.Domain.Conventions
{
    /// <summary>
    /// Setting the name of Many-to-Many tables
    /// </summary>
    public class CustomManyToManyTableNameConvention : ManyToManyTableNameConvention
    {
        protected override string GetBiDirectionalTableName(IManyToManyCollectionInspector collection, IManyToManyCollectionInspector otherSide)
        {
            return Inf.Pluralize(collection.EntityType.Name) + "_" + Inf.Pluralize(otherSide.EntityType.Name);
        }

        protected override string GetUniDirectionalTableName(IManyToManyCollectionInspector collection)
        {
            return Inf.Pluralize(collection.EntityType.Name) + "_" + Inf.Pluralize(collection.ChildType.Name);
        }
    }

    /// <summary>
    /// I use this convention to get cascade all on all the entities 
    /// that implements IAggregateRoot (empty interface), so that I 
    /// can set up a casacade-strategy
    /// </summary>
    /// <seealso cref="http://wiki.fluentnhibernate.org/Available_conventions#Interfaces"/>
    public class CustomHasManyConvention :  IHasManyConvention, IHasManyConventionAcceptance
    {
        public void Accept(IAcceptanceCriteria<IOneToManyCollectionInspector> criteria)
        {
            // Hmmm - not to happy about the GetInterface(typeof(IAggregateRoot).Name)
            // but it will have to work for now
            criteria.Expect(x => x.EntityType.GetInterface(typeof(IAggregateRoot).Name) != null);
        }

        public void Apply(IOneToManyCollectionInstance instance)
        {
            instance.Cascade.All();
        }
    }
}