简体   繁体   English

Nancy模块中的Autofac属性注入

[英]Autofac Property Injection in Nancy Module

I am using Autofac for DI and i have NacyModule like: 我正在为DI使用Autofac,并且我有NacyModule像:

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

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

My AutoFac configuration 我的AutoFac配置

In Startup.cs 在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();

in NHibernateModule.cs 在NHibernateModule.cs中

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

And in my nancy bootstraper I have something like this 在我的南希靴子里,我有这样的东西

 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>();
            });
        }
}

I now about constructor injection, works ok, and property injection works ok in other classes, but not works in nancy modules 我现在讨论构造函数注入,可以正常工作,而属性注入在其他类中也可以正常工作,但不适用于nancy模块

Note I tried adding .PropertiesAutowired() in ConfigureRequestContainer after the container update 注意我尝试在容器更新后在ConfigureRequestContainer中添加.PropertiesAutowired()

thanks. 谢谢。

The AutofacNancyBootstrapper class automatically register the module in Autofac even if the service is already registered : AutofacNancyBootstrapper类自动注册,即使该服务已经被注册在Autofac模块:

AutofacNancyBootstrapper.cs AutofacNancyBootstrapper.cs

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

With the default implementation the module is always registered and PropertiesAutoWired is not applied. 使用默认实现时,模块始终会注册,并且不会应用PropertiesAutoWired

To change this, you can override the method like this : 要更改此设置,可以覆盖如下方法:

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

Or change it like this : 或像这样更改它:

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;
}

and then register the module in your composition root 然后在您的合成根目录中注册该模块

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM