基于配置的依赖项注入
本文关键字:依赖 注入 配置 于配置 | 更新日期: 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。如果使用其他配置,则会导致构建问题。