2014-07-15 35 views
1

我試圖注入依賴關係,即我的模型,NHibernate創建。錯誤使用Autofac.Extras.NHibernate

我試圖做的是同樣在這裏:http://fabiomaulo.blogspot.com.br/2008/11/entities-behavior-injection.html

但我的容器Autofac。

所以,我發現https://www.nuget.org/packages/Autofac.Extras.NHibernate/

我看到後http://chadly.net/2009/05/dependency-injection-with-nhibernate-and-autofac/,我已經覺得是Autofac.Extras.NHibernate的起源。

我的問題是Autofac.Extras.NHibernate中的代碼和Chad post中描述的代碼是不同的。

查看源代碼,我(想)知道如何使用設置BytecodeProvider:

Cfg.Environment.BytecodeProvider = new AutofacBytecodeProvider(Container, new DefaultProxyFactoryFactory(), new DefaultCollectionTypeFactory()); 

但現在,我發現了一個例外,當我試圖從數據庫中檢索數據:

[PropertyAccessException:無法通過NHibernate.Autofac2.App_Start.Model.User.Id的反射設置器設置屬性值]

如果我註釋了設置BytecodeProvider的代碼行,代碼將起作用。

我創建了一個POC來模擬:

我的模型:

public class User 
{ 
    private readonly ISomeService _someService; 

    public User(ISomeService someService) 
    { 
     this._someService = someService; 
    } 

    public virtual long Id { get; set; } 

    public virtual string Name { get; set; } 

    public virtual string GetTranslate 
    { 
     get { return this._someService != null ? this._someService.T(this.Name) : " No Translate" + this.Name; } 
    } 
} 

我的映射:

public class UserMap : ClassMap<User> 
{ 
    public UserMap() 
    { 
     Id(x => x.Id); 
     Map(x => x.Name) 
      .Length(16) 
      .Not.Nullable(); 

    } 

} 

的Autofac容器的創建和會話工廠使用功能NHibernate:

  // Create your builder. 
     var builder = new ContainerBuilder(); 

     builder.RegisterType<SomeService>().As<ISomeService>(); 
     builder.RegisterType<User>().As<IUser>(); 

     Container = builder.Build(); 

     SessionFactory = Fluently.Configure() 
           .Database(MsSqlConfiguration.MsSql2005.ConnectionString("Data Source=(local);Initial Catalog=NHibernate.Autofac;User ID=test;Password=102030;Pooling=True")) 
           .Mappings(m => m.FluentMappings.AddFromAssemblyOf<MvcApplication>()) 
           .ExposeConfiguration(config => config.Properties.Add("use_proxy_validator", "false")) 
           .ExposeConfiguration(config => 
            { 
             //config.Properties.Add("proxyfactory.factory_class", ""); 
             Cfg.Environment.BytecodeProvider = new AutofacBytecodeProvider(Container, new DefaultProxyFactoryFactory(), new DefaultCollectionTypeFactory()); 

             new SchemaExport(config).Drop(false, false); 
             new SchemaExport(config).Create(false, true); 
            }) 
           .BuildSessionFactory(); 

回答

2

那麼,我找到了適合我的解決方案。我正在使用NHibernate.DependencyInjection

的IEntityInjector實行:

public class EntityInjector : IEntityInjector 
{ 
    private readonly IContainer _container; 

    public EntityInjector(IContainer container) 
    { 
     _container = container; 
    } 

    public object[] GetConstructorParameters(System.Type type) 
    { 
     var constructor = type.GetConstructors().FirstOrDefault(); 

     if (constructor != null) 
      return constructor.GetParameters().Select(a => a.ParameterType).Select(b => this._container.Resolve(b)).ToArray(); 

     return null; 
    } 
} 

而且在Global.asax中:

  Initializer.RegisterBytecodeProvider(new EntityInjector(Container)); 

     SessionFactory = Fluently.Configure() 
           .Database(MsSqlConfiguration.MsSql2005.ConnectionString("Data Source=(local);Initial Catalog=NHibernate.Autofac;User ID=XXX;Password=XXXX;Pooling=True")) 
           .Mappings(m => m.FluentMappings.AddFromAssemblyOf<MvcApplication>()) 
           .ExposeConfiguration(config => config.Properties.Add("use_proxy_validator", "false")) 
           .ExposeConfiguration(config => 
            { 
             new SchemaExport(config).Drop(false, false); 
             new SchemaExport(config).Create(false, true); 
            }) 
           .BuildSessionFactory();