2014-07-15 20 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();