我正在尝试在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帖子中描述的代码不同。
查看源代码我(想想)想出了如何设置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();
}
}
使用Fluent Nhibernate创建Autofac容器和SessionFactory:
// 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();
答案 0 :(得分: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();