2011-01-05 65 views
0

我想知道是否有人知道是否可以通过Unity注入正在使用的方法上的Attribute类?Unity - 注入属性类

更确切地说,我工作的项目是一个MVC2 ASP.NET类型,其中控制器实例通过Unity注入。所有依赖关系(例如数据库上下文)均在Unity配置文件中配置。

我的问题是,我如何注入自定义的Attribute类,它也使用数据库上下文,即它有一个依赖?

这里的控制器类的抽象:

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

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

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

预先感谢帮助。

N.

回答

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() 
     { 
    } 

希望这有助于 干杯 斯廷