统一自我依赖接口注册
接口依赖于相同类型的接口来完成某些特定操作。但是,当我尝试使用统一注册它我越来越统一自我依赖接口注册
类型“System.*Exception”未处理的异常 发生在Microsoft.Practices.Unity.DLL
我觉得它落入一个一种自我参考循环并填充内存。
我的方法有问题吗? 我该如何解决它?
我有这样的接口;
public interface IEnvironment
{
string RootUrl { get; set; }
string ImagesPath { get; set; }
IEnvironment DependentEnvironment { get; set; }
}
这是我的代码的运行环境,如本地主机,生产的Windows Phone模拟器等..表示
我有两个班,现在实现这个权利;
class Localhost : IEnvironment
{
public string RootUrl { get; set; }
public string ImagesPath { get; set; }
public IEnvironment DependentEnvironment { get; set; }
public Localhost(IEnvironment dependentEnvironment)
{
ImagesPath = "images";
DependentEnvironment = dependentEnvironment;
}
}
和
public class WindowsPhoneSimulator : IEnvironment
{
public string RootUrl { get; set; }
public string ImagesPath { get; set; }
public IEnvironment DependentEnvironment { get; set; }
public WindowsPhoneSimulator(IEnvironment dependentEnvironment)
{
ImagesPath = "/Assets/images";
DependentEnvironment = dependentEnvironment;
}
}
这样一个环境可以依赖另一个呢?为什么?因为例如WindowsPhoneSimulator可以对本地主机进行api调用,所以当我部署应用程序时,我会将注入更改为ProductionEnvironment。所以它应该知道要调用哪个环境。
当我开始解决我的对象时,问题就开始了;
IocContainer.RegisterType<IEnvironment, WindowsPhoneSimulator>();
有什么建议吗?
你没有显示你是如何注册你的类型,但大概你只是用一个标准的RegisterType方法注册它们。当你注册第二个类型时,它会覆盖第一个类型,所以Unity只知道你的一个类(其次是注册的类)。那么为什么你会得到一个堆栈溢出异常是有意义的,因为它试图创建一个say,WindowsPhoneSimulator类的实例以传递到WindowsPhoneSimulator类......这显然不能做到。
相反,您需要将统一类型注册为“命名类型”,然后当您想使用其中一个类时,在解析类时创建依赖覆盖,告诉Unity要使用哪一个。然后
container.RegisterType<IEnvironment, Localhost>("Localhost")
container.RegisterType<IEnvironment, WindowsPhoneSimulator>("WindowsPhoneSimulator")
当你要创建的类型,像这样:
因此,注册类型为命名类型
DependencyOverride dep = new DependencyOverride(typeof(IEnvironment)
, container.Resolve<IEnvironment>("Localhost"));
IEnvironment obj2 = container.Resolve<IEnvironment>("WindowsPhoneSimulator", dep);
在上面的例子中,你首先解决Localhost类的实例,然后使用该实例创建dependencyOverride,并将其传递给WindowsPhoneSimulator类的构造函数。因此,WindowsPhoneSimulator在构建时会传递Localhost的实例。
命名实例和DependencyOverride我在找什么。我还没有测试过,但我从你的例子中看到的逻辑完全合理。 – 2014-10-24 14:20:39
你可能想用'RegisterInstance'和手动'Resolve''依赖的环境来注册所有环境作为命名实例...也许你需要使用子容器。你应该考虑当解析()时应该发生什么 - Unity不能神奇地发现你想要的结果(我不确定是基于你的问题),所以需要一些澄清(也许名称为'Resolve (“Phone”)')。 –
2014-10-20 05:47:56