【问题标题】:Dependency injection for extension classes?扩展类的依赖注入?
【发布时间】:2016-06-22 05:15:27
【问题描述】:

我使用 Microsoft Unity 作为我的 IoC 容器。我有许多扩展类,它们为我的业务对象添加了有用的方法 这是我今天使用的那种代码:

public static class BusinessObjectExtensions
{
    public static bool CanDoStuff(this BusinessObject obj) 
    {
        var repository = BusinessHost.Resolver.Resolve<IRepository>();
        var args = new EArgument { Name = obj.Name };
        return repository.AMethod(obj.UserName, args);
    }
}

有没有更好的方法来管理扩展类的依赖注入?

【问题讨论】:

标签: c# .net ioc-container


【解决方案1】:

构造函数注入的依赖注入事实上的默认方式对于静态类是不可能的。可以像下面这样使用参数注入,但这不是一种非常干净的方法。

public static class BusinessObjectExtensions
{
    public static bool CanDoStuff(this BusinessObject obj, IRepository repository)
    {
        var args = new EArgument { Name = obj.Name };
        return repository.AMethod(obj.UserName, args);
    }
}

【讨论】:

  • 这应该是公认的答案。唯一的方法是方法注入。
  • 我们如何才能有静态变量,因为扩展类没有构造函数,所以使用非构造函数赋值?
  • @mnwsmit 你在哪里分配存储库?它是在哪里声明的?
  • 这个扩展怎么调用?
【解决方案2】:

您实际上应该尽量避免使用扩展方法,除非它们仅适用于内部数据(类本身的属性)或方法中提供的简单数据类型。您不应该在扩展方法中与其他依赖项交谈。如果您遵循此规则,则根本不需要在您的 IoC 中注入扩展类。

【讨论】:

  • 示例。我想在返回之前修剪冗长的文本。它是通过扩展方法完成的。此方法需要知道字符串的最大长度以及是否启用了修剪。在这种情况下,此知识位于配置文件中。如果不将所有这些作为参数传递给 Trim 方法,您将如何处理这个问题?
  • @Mariusz 你最好传递这个值。或者,您可以将其包装到您调用它的私有方法中;)
【解决方案3】:

你为什么要这样做?

这将您的应用程序中的耦合提高到了顶峰,并且可能会让您的队友使用扩展方法非常困惑(他们必须记住每次使用该方法时都注入存储库)。

相反,创建一个单独的类并使用构造函数注入来注入IRepository 实例:

public class StuffExecuter    
{
    private readonly IRepository _repository;

    public StuffExecuter(IRepository repository)
    {
        _repository = repository;
    }

    public bool CanExecute(BusinessObject obj)
    {
        _repository.Add(obj.UserName, new EArgument
        {
            Name = obj.Name
        });
    }
}

【讨论】:

  • 这就是我们设计的方式,但上面的示例取自一个非常具体的(如果不是完全隔离的)用例,其中我们相信将我们需要的功能挂钩到我们的业务对象。事后看来,这不是一个好主意,所以我会把它移到别处。谢谢!
猜你喜欢
  • 2014-06-05
  • 1970-01-01
  • 1970-01-01
  • 2022-10-15
  • 1970-01-01
  • 2018-12-18
  • 2011-06-23
  • 2020-04-26
  • 2017-11-02
相关资源
最近更新 更多