Прокси, открывающий доступ к нескольким интерфейсам с помощью Ninject.Extensions.Interception.Linfu

Я использую Ninject.Extensions.Interception (более конкретно, InterceptAttribute) а также Ninject.Extensions.Interception.Linfu прокси для реализации механизма ведения журнала в моем приложении C#, но я сталкиваюсь с некоторыми проблемами, когда прокси-класс реализует несколько интерфейсов.

У меня есть класс, который реализует интерфейс и наследует от абстрактного класса.

public class MyClass : AbstractClass, IMyClass {
  public string SomeProperty { get; set; }
}


public class LoggableAttribute : InterceptAttribute { ... }

public interface IMyClass {
  public string SomeProperty { get; set; }
}

public abstract class AbstractClass {

  [Loggable]
  public virtual void SomeMethod(){ ... }
}    

Когда я пытаюсь получить экземпляр MyClass из ServiceLocator, атрибут Loggable заставляет его возвращать прокси.

var proxy = _serviceLocator.GetInstance<IMyClass>();

Проблема в том, что возвращаемый прокси распознает только интерфейс AbstractClass, предоставляя SomeMethod (). Соответственно, я получаю ArgumentException когда я пытаюсь получить доступ к несуществующей SomeProperty.

//ArgumentException
proxy.SomeProperty = "Hi";

В этом случае, есть ли способ использовать mixin или какой-либо другой метод для создания прокси, выставляющего несколько интерфейсов?

Спасибо

Пауло

1 ответ

Я столкнулся с подобной проблемой, и я не нашел элегантного решения только с незначительными средствами. Так что я решил проблему с более простым шаблоном из ООП: композиция.

Применительно к вашей проблеме что-то вроде этого было бы моим предложением:

public interface IInterceptedMethods
{
    void MethodA();
}

public interface IMyClass
{
    void MethodA();
    void MethodB();
}

public class MyInterceptedMethods : IInterceptedMethods
{
    [Loggable]
    public virtual void MethodA()
    {
        //Do stuff
    }
}

public class MyClass : IMyClass
{
    private IInterceptedMethods _IInterceptedMethods;
    public MyClass(IInterceptedMethods InterceptedMethods)
    {
        this._IInterceptedMethods = InterceptedMethods;
    }
    public MethodA()
    {
        this._IInterceptedMethods.MethodA();
    }
    public Method()
    {
        //Do stuff, but don't get intercepted
    }
}
Другие вопросы по тегам