5

I'm looking for a clean pattern to use dependencies in .Net extension methods without explicitly newing-up or using a service locator:

public static class HttpContextExtensions
{
    public static SomeClass ExtensionMethod(this HttpContext context)
    {
        //looking to avoid this
        var dependency = ServiceLocator.GetService<DependencyType>();
        return dependency.DoSomething(context);
    }
}

Am I barking up the wrong tree here? Should I be looking for a more direct solution that passes context into a method? I'd like to continue using an extension if possible.

4

3 回答 3

9

在 Mark Seemann 所著的“.NET 中的依赖注入”一书中,他在第 2 章中谈到了 4 种不同的注入模式:

  1. 构造函数注入
  2. 属性注入
  3. 方法注入
  4. 环境语境

第四个,环境上下文,是一个静态属性,可以是抽象类型。此属性可以在 DI 根、线程上下文、调用上下文、请求上下文等中设置。.NET 安全、事务和其他类似的东西使用这种模式。

以下链接将为您提供更多详细信息:

这是一些示例代码:

public interface IOutput
{
    void Print(Person person);
}

public class ConsoleOutput : IOutput
{
    public void Print(Person person)
    {
        Console.WriteLine("{0} {1}", person.FirstName, person.LastName);
    }
}

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public static class SampleContext
{
    public static IOutput Output { get; set; }
}

public static class ExtensionMethods
{
    public static void Print(this Person person)
    {
        SampleContext.Output.Print(person);
    }
}

static class Program
{
    static void Main()
    {
        //You would use your DI framework here
        SampleContext.Output = new ConsoleOutput();

        //Then call the extension method
        var person = new Person()
        {
            FirstName = "Louis-Pierre",
            LastName = "Beaumont"
        };

        person.Print();
    }
}
于 2013-12-19T00:25:24.457 回答
3

您不能为此使用扩展方法。扩展方法是静态的,这意味着您不能使用构造函数注入。只有方法注入是一种选择,但这意味着您必须将依赖项作为方法参数传递,这通常很糟糕,因为依赖项通常应该是实现细节,但是方法注入使依赖项成为合同的一部分,这意味着消费者扩展方法应该知道这些依赖项(并将它们注入)。

所以解决方案是:不要对任何有依赖关系的东西使用扩展方法:为此编写一个适当的类和抽象。

于 2013-05-24T22:04:24.513 回答
0

一个可能的解决方案是让扩展方法扩展您尝试注入的类并在上游上下文中引用该依赖项,例如控制器操作或导致此调用的任何其他非静态入口点。

于 2017-11-08T19:46:47.967 回答