Autofac 属性 注入 Nancy 模块

Autofac Property Injection in Nancy Module

我正在使用 Autofac 进行 DI,我有 NacyModule,例如:

public class TestModule: NancyModule
{
    public ISessionFactory SessionFactory { get; set; }
    public IMapper Mapper { get; set; }

    public TestModule(ITestRepository testRepository)
    {
        Get("hello", _ => "hello world");
    }
}

我的 AutoFac 配置

在Startup.cs

    var builder = new ContainerBuilder();

                builder.RegisterModule(new ServicesModule());
                builder.RegisterModule(new NHibernateModule(configuration.GetConnectionString("DefaultConnection")));
                builder.RegisterModule(new AutomapperModule());
                builder.Populate(services);
                container = builder.Build();

                return new AutofacServiceProvider(container);

in ServiceModule.cs 

    builder.RegisterAssemblyTypes(ThisAssembly)
                               .Where(t => new[]
                        {
                           "Processor",
                            "Process",
                            "Checker",
                            "Indexer",
                            "Searcher",
                            "Translator",
                            "Mapper",
                            "Exporter",
                            "Repository"         }.Any(y =>
                        {
                            var a = t.Name;
                            return a.EndsWith(y);
                        }))
                    .AsSelf()
                    .AsImplementedInterfaces()
                    .PropertiesAutowired()
                    .InstancePerLifetimeScope();

在NHibernateModule.cs

    builder.Register(c => CreateConfiguration(connectionString)).SingleInstance();
    builder.Register(c => c.Resolve<Configuration>().BuildSessionFactory()).As<ISessionFactory>().SingleInstance().PropertiesAutowired();

在我的 nancy 引导程序中,我有这样的东西

 public class Bootstrapper : AutofacNancyBootstrapper
    {
        private static readonly ILogger logger = LogManager.GetLogger(typeof(Bootstrapper).FullName);

        private readonly ILifetimeScope _container;

        public Bootstrapper(ILifetimeScope container)
        {

            _container = container;
        }

        protected override ILifetimeScope GetApplicationContainer()
        {
            return _container;
        }

        public override void Configure(INancyEnvironment environment)
        {
            base.Configure(environment);

            environment.Tracing(false, true);
        }

        protected override void ConfigureRequestContainer(ILifetimeScope container, NancyContext context)
        {
            container.Update(builder =>
            {
                builder.Register(c =>
                {
                    var sf = c.Resolve<ISessionFactory>();
                    return new Lazy<NHibernate.ISession>(() =>
                    {
                        var s = sf.OpenSession();
                        s.BeginTransaction();
                        return s;
                    });
                }).InstancePerLifetimeScope();

                builder.Register(c => c.Resolve<Lazy<NHibernate.ISession>>().Value).As<NHibernate.ISession>();
            });
        }
}

我现在关于构造函数注入,工作正常,并且 属性 注入在其他 类 中工作正常,但在 nancy 模块中无效

请注意,我尝试在容器更新后在 ConfigureRequestContainer 中添加 .PropertiesAutowired()

谢谢。

即使服务已经注册,AutofacNancyBootstrapper class 也会自动在 Autofac 中注册模块:

AutofacNancyBootstrapper.cs

protected override INancyModule GetModule(ILifetimeScope container, Type moduleType)
{
    return container.Update(builder => builder.RegisterType(moduleType)
                                              .As<INancyModule>())
                    .Resolve<INancyModule>();
}

使用默认实现,模块始终被注册并且 PropertiesAutoWired 未应用。

要更改此设置,您可以像这样覆盖方法:

protected override INancyModule GetModule(ILifetimeScope container, Type moduleType)
{
    return container.Update(builder => builder.RegisterType(moduleType)
                                              .As<INancyModule>())
                    .Resolve<INancyModule>()
                    .PropertiesAutoWired();
}

或者像这样改变它:

protected override INancyModule GetModule(ILifetimeScope container, Type moduleType)
{
    INancyModule module = null;

    if (container.IsRegistered(moduleType))
    {
        module = container.Resolve(moduleType) as INancyModule;
    }
    else
    {
        IEnumerable<IComponentRegistration> registrations = container.ComponentRegistry.RegistrationsFor(new TypedService(typeof(INancyModule)));
        IComponentRegistration registration = registrations.FirstOrDefault(r => r.Activator.LimitType == moduleType);
        if (registration != null)
        {
            module = container.ResolveComponent(registration, Enumerable.Empty<Parameter>()) as INancyModule;
        }
        else
        {
            module = base.GetModule(container, moduleType);
        }
    }

    return module;
}

然后在你的合成根中注册模块

builder.RegisterType<TestModule>()
       .As<INancyModule>()
       .PropertiesAutoWired()