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

时间:2020-06-16 07:40:28

标签: dependency-injection autofac

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

Microsoft.Extensions.DependencyInjection 中:

db.collection.aggregate([
  {
    $match: {
      $expr: {
        $and: [
          {
            $eq: [ "$Company", "American Foods"]
          },
          {
            $in: [ "$Item", "$Items.name" ]
          }
        ]
      }
    }
  }
])

这在Autofac中如何工作?谢谢。

1 个答案:

答案 0 :(得分:3)

全部与注册顺序有关。 There's a section in the documentation on it.

基本上:最后一次获胜。

首先,请务必注意,示例中使用的是Microsoft.Extensions.DependencyInjection库。这些都不是Autofac。 Autofac can integrate with that,但是使用IServiceCollection设置注册的方式不是Autofac。

但是,最终获胜这一概念适用于Microsoft 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,则可以使用built in support for decoratorstype interceptors来简化生活。标准的Microsoft DI库未提供装饰器和拦截器。