2011-01-05 2 views
0

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

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

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

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

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

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

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

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

Н.

ответ

0

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

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

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

Jimmy Bogard has a series on getting more DI into an MVC app ссылка ссылается на конкретную тему по теме Фильтры действий.

1

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

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); 
    } 
} 

Для конфигурации единства добавить простое расширение перехвата.

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

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

[CustomAuthorize] 
     ActionResult Index() 
     { 
    } 

Надеется, что это помогает Приветствию Растина

Смежные вопросы