Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 统一循环参照注释对象_C#_Unity Container - Fatal编程技术网

C# 统一循环参照注释对象

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; } 统一将因此进入循环引用。 这些类都是遗

我正在尝试开发一个遗留应用程序(带有源代码),以使用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; }
统一将因此进入循环引用。
这些类都是遗留类,我不想花费太多精力去改变它们的设计,有什么办法(除了重构内部的方法)可以绕过它们吗?

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会有用

  • 解析A(实例化A)
  • 检测B依赖项
  • 解析B(实例化B)
  • 检测依赖项
  • 解析实例(由于生命周期而重用实例并完成递归)
  • 例如:

    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上运行的项目!