Как можно объединить несколько интерфейсов с несколькими классами, используя DynamicProxy? - PullRequest
2 голосов
/ 18 ноября 2010

Предположим, у нас есть интерфейс ICat, который получен из ICatBase и ICatExtension, как показано ниже.Для обоих отдельных интерфейсов доступна реализация, CatBase и CatExtension.Как можно использовать DynamicProxy Касла для объединения их в экземпляр ICat?

Возможно ли создать прокси, в котором ICatExtension реализован CatExtension, а ICatBase «реализован» перехватчиком?Как этого достичь?

public interface ICatBase
{
   string Name { get; set; }
   int Age { get; set; }
}

public interface ICatExtension
{
   string Description { get; }
}

public interface ICat : ICatBase, ICatExtension
{
}

public class CatBase : ICatBase
{
   public string Name { get; set; }
   public int Age { get; set; }
}

public class CatExtension : ICatExtension
{
   public string Description
   {
      get { return "Furry"; }
   }
}

EDIT

Я пытался использовать миксины для этой работы, но приведенный ниже код приводит к исключению NotImplementedException.

var generator = new ProxyGenerator();
var options = new ProxyGenerationOptions();
options.AddMixinInstance(new CatBase());
options.AddMixinInstance(new CatExtension());
var cat  = generator.CreateInterfaceProxyWithoutTarget<ICat>(options);        
cat.Name = "Joey";

Это ошибка DynamicProxy2: для метода 'Void set_Name (System.String)', который не имеет цели, не указаны перехватчики.При вызове метода без цели нет реализации, к которой следует «переходить», и перехватчик обязан имитировать реализацию (установить возвращаемое значение, аргументы и т. Д.)

Я мог бы создать собственный перехватчик, который перехватывает вызови отправляет на правильный интерфейс, но я чувствую, что должен быть более легкий / лучший способ.Я прав?

РЕДАКТИРОВАТЬ # 2

Спасибо, Кшиштоф!Использование линий ниже было решением.

var generator = new ProxyGenerator();
var options = new ProxyGenerationOptions();
options.AddMixinInstance(new CatBase());
options.AddMixinInstance(new CatExtension());

var cat = (ICat)generator.CreateClassProxyWithTarget(typeof(object), new[] { typeof(ICat)}, new object(), options);

EDIT # 3

В качестве последнего шага я настроил контейнер Виндзор для создания прокси из этого примера,Единственным способом, которым я смог это сделать, было указание имени «Cat» и разрешение экземпляра System.Object путем указания имени и последующего приведения к интерфейсу ICat.

WindsorContainer container = new WindsorContainer();
container.Register(
    Castle.MicroKernel.Registration.Component.For<object>().
        Named("Cat").
        Proxy.AdditionalInterfaces(typeof (ICat)).
        Proxy.MixIns(new CatBase()).
        Proxy.MixIns(new CatExtension())
    );

var cat = (ICat)container.Resolve(typeof(object), "Cat");

IsЕсть ли более элегантный способ для этого, в котором я могу просто попросить контейнер для экземпляра ICat, не ссылаясь на конкретное имя?

1 Ответ

1 голос
/ 18 ноября 2010

Mixins - это то, что вы обычно используете для этого.

...