Используя шаблон адаптера в сочетании с IoC (в частности, Unity), я хотел бы создать новый экземпляр объекта, свойства которого указывают на свойства адаптера (в основном отображение адаптера на целевой объект).
В качестве примера у меня есть следующие структуры классов:
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 = 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);
Это означает, что разрешенный экземпляр Adapter должен быть внедрен в свойство MyTarget экземпляра myTestClass. Экземпляр Adapter должен был быть создан с помощью внешнего экземпляра Adaptee.
Следующий код:
container
.RegisterType<MyTestClass>(
new InjectionProperty("MyTarget"));
должен на самом деле привести к этому:
container
.RegisterType<MyTestClass>(
new InjectionProperty("MyTarget", container.Resolve<Adapter>()));
Это кажется невозможным, поскольку ни одного экземпляра Adapter еще не существует, и у него есть собственный конструктор.
Должен ли я использовать перехват или что-то для этого?