基于配置的依赖项注入

本文关键字:依赖 注入 配置 于配置 | 更新日期: 2023-09-27 18:19:26

我正在开发一个使用active directory检索用户的应用程序。有时我需要在应用程序上工作,但AD不可用。我使用包装类来检索AD用户。我想根据配置注入一个不同的类。我正在考虑使用一个appSetting,它会告诉我当前的配置,并决定在注入时使用什么类型。是否可以在不使用Web.config转换的情况下获得当前配置?是否可以使用基于Web.config转换的Unity注入对象?你能推荐一个更好的方法吗?

[更新]

我有一个从AD加载用户的用户存储库类。我所需要的只是能够更改此存储库类的实现,以便在AD不可用时,我可以以不同的方式加载用户。这将只用于开发,生产将始终访问AD并检索用户。

基于配置的依赖项注入

您可以使用预处理器指令:

#if DEBUG
// register fake repository
#else
// register AD repository
#endif

依赖注入非常强大、敏捷,并创建了关注点分离。你的方法的缺陷将来自于验证。你看,使用这种方法,你必须选择一个具体的实现。

那么,你将如何称呼这两个类呢?

public class LogToText : ILogger
{
     public void LogMessage(string message) { }
}
public class LogToEvent : ILogger
{
     public void LogMessage(string message) { }
}

您有这两种实现,但当您将接口传递给:时

public class AD
{
     public AD(ILogger logger) { }
}

因此,问题将是你是否觉得你可以正确地验证,以有效地选择正确的实现。否则,依赖注入可能无法正常工作。我们并不完全知道用法或目标,所以我们的建议可能并不是真正有益的。希望你明白我的意思,因为你必须看看你是否不能测试特定的方式。

您可以使用抽象:

public interface IPersonService
{
    IEnumerable<Person> Find(PersonSearchParameters searchParams);
    Person GetByAccountName(string accountName);
    [ETC...]
}

然后您的AD和Development都实现了这个接口。

为了让事情变得更容易,我建议使用StructureMap IoC,这样你就可以很容易地做到这一点:

x.For<IPersonService>.Use<ActiveDirectoryPersonService>(); //for production

x.For<IPersonService>.Use<MockPersonService>(); //for development

当使用这个时,你可以,例如:

public class TestController : Controller
{
    IPersonService _service;
    public TestController(IPersonService service)
    {
        _service = service;
    }
}

在这种情况下,我建议不要使用XML文件进行配置,而是使用Structure Map的Fluent代码,这样在重构时会更好,并避免因为编译而导致错误键入。

结构图:http://structuremap.net

可通过NuGET 轻松安装

另一种方法是使用从程序集读回的构建配置。

var buildConfiguration = typeof(Program).Assembly.GetCustomAttribute<AssemblyConfigurationAttribute>()?.Configuration;
if (buildConfiguration == "Debug")
{
    // register fake repository
}
else
{
    // register AD repository
}

然后应用重构或自动代码清理(例如ReSharper等)会更安全。根据您当前的配置,代码清理可以删除未使用的using。如果使用其他配置,则会导致构建问题。