扩展类的依赖注入?

26

我正在使用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);
    }
}

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


我认为它没有显示出需要成为“扩展方法”的任何要求...所以有很多依赖对象。 - Moumit
相关:https://dev59.com/_HHYa4cB1Zd3GeqPMogd - Steven
3个回答

32

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

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

6
应该接受这个答案。唯一的方法是使用方法注入。 - tocqueville
我们如何使用非构造函数分配静态变量,因为扩展类没有构造函数? - kudlatiger
@mnwsmit,您在哪里分配了存储库?它在哪里声明? - kudlatiger
3
这个扩展应该怎么称呼? - Peyman Majidi

23

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


我想在返回文本之前对其进行修剪。这可以通过扩展方法完成。该方法需要知道字符串的最大长度以及是否启用了修剪。在这种情况下,此知识包含在配置文件中。如果要避免将所有这些作为参数传递给 Trim 方法,您会如何解决? - Mariusz
2
@Mariusz,你最好传递那个值。你可以将它包装到一个私有方法中,在那里调用它 ;) - J.Wincewicz
不是内部数据,而是公共数据。 - Wouter
1
@Mariusz 为什么只有扩展方法是解决你问题的方案?你也可以创建一个帮助类,并使用它的注入对象来执行该操作。 - Umair Tahir
@UmairTahir 是的,另一个服务也可以。不过扩展方法会是我的首选,因为没有必要注入额外的服务。 - Mariusz
但您仍然在注入服务以停止注入服务 :) - Umair Tahir

6

为什么要这样做?

这会增加应用程序的耦合度,并且对于您的团队成员来说,使用扩展方法可能非常困惑(他们必须记住每次使用该方法时注入存储库)。

相反,创建一个单独的类并使用构造函数注入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
        });
    }
}

1
这是我们按设计方式操作的,但上面的例子来自一个非常特定的、甚至可以说是孤立的用例,在那里我们相信将所需的功能挂钩到我们的业务对象中会很方便。回想起来,这不是一个好主意,所以我会把它移到其他地方。谢谢! - Leonard
我想注入一个记录器,以便能够从扩展方法中进行日志记录。 - Wouter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接