使用Autofac.Extras.NHibernate时出错

时间:2014-07-15 21:08:59

标签: nhibernate autofac

我正在尝试在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();

1 个答案:

答案 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();