我有分层的asp.net MVC应用程序。 在服务层,我有一个容器来注册依赖项。例如:
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<ISomething, Something>();
}
根据设计,我们需要有一个模拟实现 如果用户决定打开应用程序进行测试,则为类。
所以,我提出了像
这样的想法 public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<ISomething, Something>();
container.RegisterType<ISomething, SomethingMock>();
}
如果我在某处使用标记来指示系统是否在测试模式下运行,那么如何决定在运行时解析哪个依赖项? 如果它不是一个优雅的解决方案,还有什么可以替代?
答案 0 :(得分:3)
如果我在某处使用标记来指示系统是否在测试模式下运行,那么如何决定在运行时解析哪个依赖项?
您不应该根据运行时决策更改对象图的结构。这与anti-pattern of injecting runtime data into components非常相关。
如果您需要根据运行时条件切换实现(意味着:值可能会从请求更改为请求),解决方案是创建一个实现var milliseconds = nowDate.getTime() - date.getTime();
并包装两个ISomething
的代理类实现(this article显示了一些代理实现的例子)。调用ISomething
时,它可以根据它在此时确定的运行时条件将调用转发给正确的实现。
但是,在您的情况下,您很可能不会讨论运行时条件,而是讨论配置值。配置值在应用程序的生命周期内不会发生变化。只有在重新启动(或重新部署)后,您才会看到值的变化。
这意味着您只需在启动时读取配置值,然后决定应该注册哪个实现:
ISomething.Method
答案 1 :(得分:1)
虽然我完全支持史蒂文斯的回答和他的考虑,但在技术上有一种方法可以做你想要的。 您可以使用命名注册:
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<ISomething, Something>();
container.RegisterType<ISomething, SomethingMock>("SomethingMock");
}
然后使用字符串参数来解决它:
string s= "";
var mySomething = container.Resolve<ISomething>(s); // will return standard implementation
s = "SomethingMock"
var mySomething = container.Resolve<ISomething>(s); // will return mock implementation
当asp想要解决ISomething时你需要拦截。
供参考,请参阅 https://msdn.microsoft.com/en-us/library/ff660923%28v=pandp.20%29.aspx
现在它取决于你走哪条路。