Конфигурация перехвата Unity — как сделать менее подробным?

#.net #configuration #unity-container #app-config #configuration-files

#.net #конфигурация #unity-контейнер #app-config #конфигурация-файлы

Вопрос:

Чтобы настроить перехват в Unity 2.0, вы добавляете что-то вроде этого в свою конфигурацию (взято из документации Unity)…

       <policy name="addDataAccessTypes">
        <matchingRule name="DataLayerMatch" type="NamespaceMatchingRule">
          <constructor>
            <param name="namespaceName" value="MyApp.DataAccess" />
          </constructor>
        </matchingRule>
        <callHandler name="LogHandler" type="LoggingCallHandler" />
        <callHandler name="SecurityHandler"
            type="DatabaseSecurityCheckHandler" />
      </policy>
  

Есть ли способ настроить несколько интерфейсов для inteception с одним и тем же классом обработки?

Например, что-то вроде этого…

 <constructor>
    < interface to intercept 1 />
    < interface to intercept 2 />
</construtor>
  

С помощью метода, приведенного в примере unity, ваш конфигурационный файл становится очень подробным, если у вас много перехватываемых интерфейсов.

Ответ №1:

Вы можете выполнять перехваты с атрибутами более плавным способом, если используете Unity.Interception сборку. Недостатком этого является то, что перехваченный класс (каким-то образом) знает об аспекте:

Очень краткий пример настройки выглядит следующим образом:

 class Program
{
    static void Main(string[] args)
    {
        try
        {
            Console.WriteLine();
            Console.WriteLine("Starting test...");

            var container = new UnityContainer();
            container.AddNewExtension<Interception>();
            container.Configure<Interception>()
                .SetDefaultInterceptorFor<IGadget>(new InterfaceInterceptor());

            container.RegisterType<IGadget, Gadget>();

            var gadget = container.Resolve<IGadget>();
            gadget.DoSomething();
        }
        catch (Exception ex)
        {
            Console.WriteLine();
            Console.WriteLine("An error has occurred: {0}", ex);
        }
        finally
        {
            Console.WriteLine();
            Console.WriteLine("Test complete.");
            Console.ReadKey();
        }
    }
}



public class LogAttribute : HandlerAttribute
{
    public override ICallHandler CreateHandler(IUnityContainer container)
    {
        return container.Resolve<LogHandler>();
    }
}

public class LogHandler : ICallHandler
{
    public int Order { get; set; }

    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        Console.WriteLine("*** Logging the action! -{0}-", input.MethodBase.Name);
        return getNext()(input, getNext);
    }
}

public interface IGadget
{
    void DoSomething();
}

[Log]
public class Gadget : IGadget
{
    public void DoSomething()
    {
        Console.WriteLine("tI did something!");
    }
}
  

Комментарии:

1. Хорошая идея, но нужно сделать это в конфигурации.

2. Я не уверен, о чем вы говорите. Вы имеете в виду, что по какой-то причине вы ограничены выполнением этого в конфигурации? Я предлагал свое решение в качестве альтернативы необходимости выполнять какие-либо настройки в файле конфигурации.