开发者

Unity - Inject an Attribute class

I was wondering if someone knows if it's possible to inject, via Unity, the Attribute class, which is being used on a method?

To be more precise, the project I work on is an MVC开发者_如何学编程2 ASP.NET type, where the controller instances are being injected via Unity. All the dependencies, such as DB Contexts are configured in the Unity configuration file.

My question is, how can I inject the custom Attribute class, which also uses a DB Context, i.e. it has a dependency?

Here's an abstract of the controller class:

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

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

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

Thanks in advance for help.

N.


What you will need to do is to make your CustomAuthorize Attribute inherit from Microsoft.Practices.Unity.InterceptionExtension.HandlerAttribute and override the "ICallHandler CreateHandler(IUnityContainer container)" method.

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

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

Now create a derived interface from Microsoft.Practices.Unity.InterceptionExtension.ICallHandler and add your IDBContext as a member.

public interface IAuthorizeAttributeHandler : ICallHandler
{
 IDBContext DBContext;
}

IAuthorizationAttributeHandler implementation

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

To your unity configuration add simple interception extension.

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

Added the attribute to the interface method you wish to have the aspect execute.

[CustomAuthorize]
        ActionResult Index()
        {
    }

Hope this helps Cheers Rustin


It's not completely impossible, but it's very difficult.

The issue is that the attribute objects themselves are created by the CLR (the reflection API in particular, if I understand it correctly), so there's no way to get a container in there to call the constructor. And you don't have any real control over when the attribute instances are created, so you can't even guarantee if your container will be ready in time.

You could write a custom ActionInvoker that would spin through attributes and call BuildUp on each one, then plug that into the MVC pipeline. It's hard work though.

Jimmy Bogard has a series on getting more DI into an MVC app, the link points to the specific topic on Action Filters.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜