c# - 如何使用Autofac在构造函数中注入(inject)具体实现

标签 c# asp.net-mvc dependency-injection autofac

我有两个将 ILastActivityUpdator 作为构造函数参数的类:UserServiceAnonymousUserService

public AnonymousUserService(ILastActivityUpdator lastActivityUpdator)
{
    if (lastActivityUpdator == null)
    {
        throw new ArgumentNullException("lastActivityUpdator");
    }
    this.lastActivityUpdator = lastActivityUpdator;
}

与上面的 UserService 类似:

public UserService(ILastActivityUpdator lastActivityUpdator)
{
    if (lastActivityUpdator == null)
    {
        throw new ArgumentNullException("lastActivityUpdator");
    }
    this.lastActivityUpdator = lastActivityUpdator;
}

ILastActivityUpdator 接口(interface)有一个方法:UpdateLastActivity(int userId)。该接口(interface)有两个实现,一个是 LastActivityUpdator,一个是 AnonymousUserLastActivityUpdator 装饰器,它继承自 LastActivityUpdator 并为该方法添加了一些额外的功能,例如所以:

public class AnonymousUserLastActivityUpdator 
    : LastActivityUpdator, IAnonymousUserLastActivityUpdator
{
    public AnonymousUserLastActivityUpdator()
    { }

    public override void UpdateLastActivity(int userId)
    {
        base.UpdateLastActivity(userId);

        // Extra functionality
    }
}

我现在想使用 Autofac 将 AnonymousUserServiceAnonymousUserLastActivityUpdator 以及 UserServiceLastActivityUpdator 连接起来.

我尝试的是为从基本接口(interface)派生的装饰器添加一个接口(interface),如下所示:

public interface IAnonymousUserLastActivityUpdator : ILastActivityUpdator
{ }

然后我想我可以在 AnonymousUserService 构造函数中使用 IAnonymousUserLastActivityUpdator,一切都会正确地 Autowiring 。

不幸的是,它总是使用第一个实现,即 IAnonymousUserLastActivityUpdator,因为它注册较早(按字母顺序)。

我怎样才能让 AnonymousUserService 获得 AnonymousUserLastActivityUpdator 注入(inject),而 UserService 获得 LastActivityUpdator

最佳答案

Autofac 是 nicely documented看起来你可以找到你想要的here .据我所知,如果您已通过

注册您的更新程序
builder.RegisterType<LastActivityUpdator>();
builder.RegisterType<AnonymousUserLastActivityUpdator>();

那么你应该可以注册你的服务了

builder.Register(c => new UserService(c.Resolve<LastActivityUpdator>()));
builder.Register(c => new AnonymousUserService(c.Resolve<AnonymousUserLastActivityUpdator>()));

builder.RegisterType<UserService>().WithParameter(
    (p, c) => p.ParameterType == typeof(ILastActivityUpdator),
    (p, c) => c.Resolve<LastActivityUpdator>());

builder.RegisterType<AnonymousUserService>().WithParameter(
    (p, c) => p.ParameterType == typeof(ILastActivityUpdator),
    (p, c) => c.Resolve<AnonymousUserLastActivityUpdator>());

然后当您从容器中解析 UserServiceAnonymousUserService 时,它们将获得正确的依赖项。

顺便说一句,如果一个接口(interface)被注入(inject)到一个类中,那么该类应该与该接口(interface)的所有实现一起正常运行(LSP)。从类名来看,AnonymousUserService 似乎只适用于 AnonymousUserLastActivityUpdator 而不是 ILastActivityUpdator 的任何实现。如果是这种情况,那么按照您的建议引入不同的抽象(如 IAnonymousUserLastActivityUpdator)可能是合适的。

关于c# - 如何使用Autofac在构造函数中注入(inject)具体实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30835744/

相关文章:

c# - 如何在wpf中隐藏面板后面的项目

c# - 从中间有非数字的字符串中解析数字

c# - 如何使用 DI usinq autofac .net 框架注册 ILogger(Microsoft.Extensions.Logging)

dependency-injection - 温莎城堡注册

c# - 将 PerWcfSession 生活方式与 CaSTLe WCF 集成工具结合使用

c# - 在 C# 中解码 PCX 图像以显示为位图

c# - 如何在 MVC Razor 中显示 TimeSpan

c# - 使用 Entity Framework 更新带有子集合的对象导致数据库中出现重复项

c# - ASP.NET MVC Razor 中新的空条件运算符

java - Eclipse 4 注入(inject) OSGI 服务