Autofac如何替换已注册的服务?

问题描述 投票:0回答:1

我想写一个AOP框架(为了学习),我需要替换已经在Autofac注册的服务。

Microsoft.Extensions.DependencyInjection(依赖注入)

        public static IServiceCollection BuildAopProxy(this IServiceCollection service)
        {
            if (service is null)
                throw new ArgumentNullException(nameof(service));

            IServiceCollection proxyServiceCollection = new ServiceCollection();

            foreach (ServiceDescriptor item in service)
            {
                Type newType;
                Type serviceType = item.ServiceType;
                Type implementationType = item.ImplementationType;

                if (serviceType == implementationType)
                {
                    newType = DynamicProxy.CreateProxyClassType(item.ImplementationType, true);
                }
                else
                {
                    newType = DynamicProxy.CreateProxyClassType(item.ServiceType, item.ImplementationType, false);
                }
                proxyServiceCollection.Add(ServiceDescriptor.Describe(serviceType, newType, item.Lifetime));
            }
            return proxyServiceCollection;
        }

在Autofac中如何操作?谢谢。

autofac
1个回答
3
投票

都是关于注册顺序的。在文档中,有一节是关于这个问题的。

基本上是这样的。最后加入的人获胜

首先,需要注意的是,你在例子中使用的是Microsoft.Extensions.DependencyInjection库。这些都不是Autofac。Autofac 可以 整合 随之但你设置你的注册的方式,使用的是 IServiceCollection 不是Autofac。

然而,这个概念 垫底 适用于微软DI和Autofac......以及几乎所有其他DI容器。

如果我注册了三个实现相同接口的东西... ...

svcCollection.AddTransient<IDependency, First>();
svcCollection.AddTransient<IDependency, Second>();
svcCollection.AddTransient<IDependency, Third>();

如果你解决 IDependency 你会得到 Third:

var provider = svcCollection.BuildServiceProvider();
var dependency = provider.GetService<IDependency>();
// dependency.GetType() == typeof(Third)

如果你真的想在这里使用Autofac,你需要使用Autofac.Extensions.DependencyInjection把所有的注册放到Autofac中。

var builder = new ContainerBuilder();
builder.Populate(svcCollection);
var container = builder.Build();

var dependency = container.Resolve<IDependency>();
// dependency.GetType() == typeof(Third)

或者你可以直接切换到使用原生的Autofac注册。

var builder = new ContainerBuilder();
builder.RegisterType<First>().As<IDependency>();
builder.RegisterType<Second>().As<IDependency>();
builder.RegisterType<Third>().As<IDependency>();
var container = builder.Build();

var dependency = container.Resolve<IDependency>();
// dependency.GetType() == typeof(Third)

看来你所做的部分工作是试图将一些组件包裹在装饰器或代理中。如果你使用原生的Autofac,那么就有 内置支持装饰者拦路虎 这可能会让你的生活更轻松。标准的微软DI库不提供装饰器和拦截器。

© www.soinside.com 2019 - 2024. All rights reserved.