views:

442

answers:

1

I'm trying to use the automap functionality in fluent to generate a DDL for the following model and program, but somehow I keep getting the error "Association references unmapped class: IRole" when I call the GenerateSchemaCreationScript method in NHibernate. When I replace the type of the ILists with the implementation of the interfaces (User and Role) everything works fine. What am I doing wrong here? How can I make fluent use the implemented versions of IUser and IRole as defined in Unity?

public interface IRole
{
   string Title { get; set; }
   IList<IUser> Users { get; set; }
}

   public interface IUser
   {
       string Email { get; set; }
       IList<IRole> Roles { get; set; }
   }

public class Role : IRole
{
   public virtual string Title { get; set; }
   public virtual IList<IUser> Users { get; set; }
}
public class User : IUser
{
   public virtual string Email { get; set; }
   public virtual IList<IRole> Roles { get; set; }
}

I use the following program to generate the DDL using the GenerateSchemaCreationScript in NHibernate:

class Program
{
   static void Main(string[] args)
   {
       var ddl = new NHibernateSessionManager();
       ddl.BuildConfiguration();
   }
}

   public class NHibernateSessionManager
   {
       private ISessionFactory _sessionFactory;
       private static IUnityContainer _container;

       private static void InitContainer()
       {
           _container = new UnityContainer();
           _container.RegisterType(typeof(IUser), typeof(User));
           _container.RegisterType(typeof(IRole), typeof(Role));
       }

       public ISessionFactory BuildConfiguration()
       {
           InitContainer();
           return
Fluently.Configure().Database(MsSqlConfiguration.MsSql2008
                .ConnectionString("ConnectionString"))
                .Mappings(m => m.AutoMappings.Add(
                    AutoMap.AssemblyOf<IUser>()))
                .ExposeConfiguration(BuildSchema)
                .BuildSessionFactory();
       }

       private void BuildSchema(Configuration cfg)
       {
           var ddl = cfg.GenerateSchemaCreationScript(new
NHibernate.Dialect.MsSql2008Dialect());
           System.IO.File.WriteAllLines("Filename", ddl);
       }

   }
A: 

You can't provide an interface as the type T in AssemblyOf<T>, you need to provide a concrete type. Or you could use the method that accepts an assemply:

.Mappings(m => m.AutoMappings.Add(
                AutoMap.Assembly(myAssembly)))

Edit: The problem is that your classes contain collections of interface types instead of class type. I don't know if it's possible to automap interfaces in this manner. Also, I think there's rarely any value in using interfaces to specify domain objects.

Jamie Ide
Sorry about that - It should of course be:.Mappings(m => m.AutoMappings.Add( AutoMap.AssemblyOf<User>()))But my problem is still the same, I get errors on:public virtual IList<IUser> Users { get; set; } andpublic virtual IList<IRole> Roles { get; set; }Any ideas how to solve this?
Bjarke
See the edit to my original answer.
Jamie Ide
According to http://steve-fair-dev.blogspot.com/2009/10/nhibernate-entity-property-is-interface.html it is possible to tell NHibernate which implementation it should use for an interface (using mapping-files). I'm just wondering if there is a way to let automapping in Fluent know the same thing?
Bjarke