C# 统一循环参照注释对象
我正在尝试开发一个遗留应用程序(带有源代码),以使用Unity实现IoC。 我目前面临的问题是,我有两个类彼此循环引用 A类参考B类 B类参考A类 我使用带有注释的属性setter注入每个依赖项C# 统一循环参照注释对象,c#,unity-container,C#,Unity Container,我正在尝试开发一个遗留应用程序(带有源代码),以使用Unity实现IoC。 我目前面临的问题是,我有两个类彼此循环引用 A类参考B类 B类参考A类 我使用带有注释的属性setter注入每个依赖项 On class A: [Dependency] public IServiceA ServiceA { get; set; } On class B: [Dependency] public IServiceB ServiceB { get; set; } 统一将因此进入循环引用。 这些类都是遗
On class A:
[Dependency]
public IServiceA ServiceA { get; set; }
On class B:
[Dependency]
public IServiceB ServiceB { get; set; }
统一将因此进入循环引用。
这些类都是遗留类,我不想花费太多精力去改变它们的设计,有什么办法(除了重构内部的方法)可以绕过它们吗?Unity将在您尝试解决问题时执行这些步骤
Create A
Look at Properties for A and create them
Found B will create B
Look at Properties for B and create them
Found A will Create A
你陷入了困境
最好的选择是创建A和B所依赖的C。但是C不依赖于A或B。我同意重构是最佳实践,但您可以通过将其中一个或两个属性更改为“惰性”来实现您的目标。在使用该属性之前,Unity不会解析另一个实例
On class A:
[Dependency]
public Lazy<IServiceA> ServiceA { get; set; }
On class B:
[Dependency]
public Lazy<IServiceB> ServiceB { get; set; }
关于A类:
[依赖性]
公共惰性服务a{get;set;}
B类:
[依赖性]
公共惰性服务b{get;set;}
或者您可以更改它们的注册生存期,以便它们重用相同的实例。但是,如果不希望共享相同的实例,这可能不适用于您。也许PerresolveLife会有用
container.RegisterType<A>(new PerResolveLifetimeManager());
container.RegisterType(新的PerResolveLifetimeManager());
这确实是一个令人沮丧的团结限制。但是,有一个2通解决方案:
[TestClass]
public class UnityTests
{
[TestMethod]
public void Cure_For_UnityNotBeingVerySmartAtBindingCircularDependentProperties()
{
var container = new UnityContainer();
container.RegisterType<ISharedResource, SharedResource>(new ContainerControlledLifetimeManager());
container.RegisterType<ICycleA, CycleA>(new ContainerControlledLifetimeManager(), new InjectionProperty("SharedResource"));
container.RegisterType<ICycleB, CycleB>(new ContainerControlledLifetimeManager(), new InjectionProperty("SharedResource"));
var a = container.Resolve<ICycleA>();
var b = container.Resolve<ICycleB>();
container.RegisterType<ICycleA, CycleA>("buildup", new ContainerControlledLifetimeManager());
container.RegisterType<ICycleB, CycleB>("buildup", new ContainerControlledLifetimeManager());
container.BuildUp(a, "buildup");
container.BuildUp(b, "buildup");
Assert.IsInstanceOfType(a, typeof(CycleA));
Assert.IsInstanceOfType(a.Dependency, typeof(CycleB));
Assert.AreSame(a, a.Dependency.Dependency);
}
}
internal interface ISharedResource { }
class SharedResource : ISharedResource { }
class CycleB : ICycleB
{
[Dependency]public ISharedResource SharedResource { get; set; }
[Dependency]public ICycleA Dependency { get; set; }
}
class CycleA : ICycleA
{
[Dependency]public ISharedResource SharedResource { get; set; }
[Dependency]public ICycleB Dependency { get; set; }
}
interface ICycleB
{
[Dependency]ISharedResource SharedResource { get; set; }
[Dependency]ICycleA Dependency { get; set; }
}
interface ICycleA
{
[Dependency]ISharedResource SharedResource { get; set; }
[Dependency]ICycleB Dependency { get; set; }
}
[TestClass]
公共类单元测试
{
[测试方法]
单元的公共无效修复不存在于MARTATBindingCirculardDependentProperties()中
{
var container=new UnityContainer();
RegisterType(新的ContainerControlledLifetimeManager());
RegisterType(新的ContainerControlledLifetimeManager(),新的InjectionProperty(“SharedResource”);
RegisterType(新的ContainerControlledLifetimeManager(),新的InjectionProperty(“SharedResource”);
var a=container.Resolve();
var b=container.Resolve();
RegisterType(“build”,新的ContainerControlledLifetimeManager());
RegisterType(“build”,新的ContainerControlledLifetimeManager());
容器。堆积物(a,“堆积物”);
容器。堆积物(b,“堆积物”);
IsInstanceOfType(a,typeof(CycleA));
Assert.IsInstanceOfType(a.Dependency,typeof(CycleB));
Assert.arame(a,a.Dependency.Dependency);
}
}
内部接口ISharedResource{}
类SharedResource:IsSharedResource{}
类CycleB:iccycleb
{
[Dependency]公共ISharedResource SharedResource{get;set;}
[Dependency]公共ICycleA依赖项{get;set;}
}
类CycleA:IcCyclea
{
[Dependency]公共ISharedResource SharedResource{get;set;}
[Dependency]公共ICycleB依赖项{get;set;}
}
接口ICycleB
{
[Dependency]IsSharedResource SharedResource{get;set;}
[Dependency]ICycleA Dependency{get;set;}
}
界面环
{
[Dependency]IsSharedResource SharedResource{get;set;}
[Dependency]ICycleB Dependency{get;set;}
}
它利用了InjectionProperty重载,它告诉Unity只连接指定的依赖项
如果您的类有一个共享资源(例如日志服务),请在第一个过程中注册此依赖项,最后一个构建过程将所有类连接在一起
它确实需要一个调用来解析和构建所有类,这有点尴尬,但可以通过UnityContainer扩展相当容易地实现自动化
这应该由Microsoft解决,因为这是一个相当标准的用例。谢谢David!,我已经知道这方面的方法,只是重构现有类所需的支持可能有点太大了!(希望有一个解决办法)lolI已经通过重构解决了这个问题,在此之前,我也尝试过使用同样有效的PerResolveLifeTime,但我无法使用Lazy,因为它适用于在.NET3.5上运行的项目!