代码之家  ›  专栏  ›  技术社区  ›  Schalk

解析没有公共构造函数的外部创建的对象实例

  •  0
  • Schalk  · 技术社区  · 17 年前

    使用适配器模式,结合IOC(具体的统一性),我想创建一个对象的新实例,该对象的属性指向适配器的属性(基本上将适配器映射到目标对象)。

    例如,我有以下类结构:

    public class Adaptee
    {
        private Adaptee() { }
    
        public int MyProperty { get; set; }
    
        public static Adaptee New()
        {
            return new Adaptee();
        }
    }
    
    public class Target
    {
        public int MyProperty { get; set; }
    }
    
    public class Adapter : Target
    {
        public Adapter(Adaptee adaptee)
        {
            this.MyProperty = adaptee.MyProperty;
        }
    }
    
    public class MyTestClass
    {
        public Target MyTarget { get; set; }
    }
    

    问题是,适配器不在我的控制之下,它没有公共构造函数,因此使用了适配器。所以adaptee创建如下

    Adaptee adaptee = Adaptee.New();
    adaptee.MyProperty = 5;
    

    在实际代码中,上述代码将在外部控制的程序集中执行,然后传递给以下代码:

    using (UnityContainer container = new UnityContainer())
    {
        container
            .RegisterType<MyTestClass>(
                new InjectionProperty("MyTarget"));
    
        container.RegisterInstance<Adaptee>(adaptee, new ExternallyControlledLifetimeManager());
    
        MyTestClass myTestClass = container.Resolve<MyTestClass>();
    }
    

    我希望代码的执行会导致以下结果:

    Debug.Assert(myTestClass != null);
    Debug.Assert(myTestClass.MyTarget != null);
    Debug.Assert(myTestClass.MyTarget.MyProperty == adaptee.MyProperty);
    

    这意味着应将适配器的已解析实例注入MyTestClass实例的MyTarget属性中。适配器的实例应该是用外部创建的adaptee实例创建的。

    以下代码:

    container
        .RegisterType<MyTestClass>(
            new InjectionProperty("MyTarget"));
    

    实际结果应该是:

    container
        .RegisterType<MyTestClass>(
            new InjectionProperty("MyTarget", container.Resolve<Adapter>()));
    

    这似乎是不可能的,因为适配器的实例还不存在,并且它有一个私有的构造函数。

    我应该使用拦截还是其他方法来实现这一点?

    2 回复  |  直到 17 年前
        1
  •  1
  •   Community Mohan Dere    9 年前

    我和 container.Resolve<Adapter>() 想法,但最终的答案只是使用 解析参数 当配置要使用 注入特性 班级:

    new InjectionProperty(
      "MyTarget", 
      new ResolvedParameter<Adapter>()));
    

    因此,调用代码如下所示:

    Adaptee adaptee = Adaptee.New();
    adaptee.MyProperty = 5;
    
    using (UnityContainer container = new UnityContainer())
    {
        container
            .RegisterType<MyTestClass>(
                new InjectionProperty(
                  "MyTarget",
                  new ResolvedParameter<Adapter>()));
    
        container.RegisterInstance<Adaptee>(adaptee, new ExternallyControlledLifetimeManager());
    
        MyTestClass myTestClass = container.Resolve<MyTestClass>();
    }
    

    我在下面的文章中找到了解决方案: Setter / property injection in Unity without attributes

    希望这对其他人有帮助。

        2
  •  0
  •   Schalk    17 年前

    那是一个多哈!时刻。

    解决方案是在配置Unity时添加以下内容:

    .RegisterType<Target, Adapter>()
    

    我真不敢相信我错过了这个,一个解决问题的简单方法(我想)。

    因此,myTestClass上的te myTarget属性将解析为适配器的实例,因为它继承自目标。显然,适配器将使用外部创建的adaptee类实例启动。