Unity - внедрить класс атрибутов - PullRequest
0 голосов
/ 05 января 2011

Мне было интересно, знает ли кто-нибудь, возможно ли внедрить через Unity класс Attribute, который используется в методе?

Точнее говоря, проект, над которым я работаю, - это MVC2 ASPТип .NET, где экземпляры контроллера внедряются через Unity.Все зависимости, такие как контексты БД, настраиваются в файле конфигурации Unity.

Мой вопрос: как я могу внедрить пользовательский класс атрибутов, который также использует контекст БД, то есть он имеет зависимость?

Вот краткое описание класса контроллера:

    public class MyController : Controller
    {
        public IDBContext MyDBContext { get; set; }
...

    [CustomAuthorize]
    public ActionResult Index()
    {
...

    public class CustomAuthorize : AuthorizeAttribute
    {
        public IDBContext2 MyDBContext2 { get; set; }
...

Заранее спасибо за помощь.

N.

Ответы [ 2 ]

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

Что вам нужно сделать, это заставить свой атрибут CustomAuthorize наследовать от Microsoft.Practices.Unity.InterceptionExtension.HandlerAttribute и переопределить метод «ICallHandler CreateHandler (IUnityContainer container)».

public class CustomAuthorizeAttribute: HandlerAttribute
{
   public IAuthorizeAttributeHandler AuthorizationHandler { get; set; }

    public override ICallHandler CreateHandler(IUnityContainer container)
    {
       AuthorizationHandler= new AuthorizationAttributeHandler
     {
         DBContext = container.Resolve<IDBContext>()
     };
     return AuthorizationHandler;
    }
}

Теперь создайтепроизводный интерфейс от Microsoft.Practices.Unity.InterceptionExtension.ICallHandler и добавьте свой IDBContext в качестве члена.

public interface IAuthorizeAttributeHandler : ICallHandler
{
 IDBContext DBContext;
}

Реализация IAuthorizationAttributeHandler

public class AuthorizationAttributeHandler : IAuthorizeAttributeHandler
{
public IDBContext DBContext
        {
            get; set;
        }

    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
         var result = DBContext.DoWork(input.Arguments..);

//// Invoke the handler
            IMethodReturn output = getNext()(input, getNext);

return getNext()(input, getNext);
    }
}

В свою конфигурацию Unity добавьте простое расширение перехватывания.

unityContainer  
                .AddNewExtension<Interception>()
                .Configure<Interception>()
                .SetInterceptorFor<IYourPageInterface>(new InterfaceInterceptor());

Добавлен атрибут в метод интерфейса, для которого вы хотите, чтобы аспект выполнялся.

[CustomAuthorize]
        ActionResult Index()
        {
    }

Надеюсь, это поможет Cheers Rustin

0 голосов
/ 06 января 2011

Это не совсем невозможно, но это очень сложно.

Проблема заключается в том, что сами объекты атрибутов создаются CLR (в частности, API отражения, если я правильно понимаю), поэтому нет способа поместить туда контейнер для вызова конструктора. И у вас нет реального контроля над при создании экземпляров атрибутов, поэтому вы даже не можете гарантировать, что ваш контейнер будет готов вовремя.

Вы можете написать собственный ActionInvoker, который будет прокручивать атрибуты и вызывать BuildUp для каждого, а затем подключать его к конвейеру MVC. Хотя это тяжелая работа.

У Джимми Богарда есть серия статей о том, как добавить больше DI в приложение MVC , ссылка указывает на конкретную тему о фильтрах действий.

...