【问题标题】:Unity - Inject an Attribute classUnity - 注入一个属性类
【发布时间】:2011-01-05 14:12:32
【问题描述】:

我想知道是否有人知道是否可以通过 Unity 注入用于方法的 Attribute 类?

更准确地说,我从事的项目是一个 MVC2 ASP.NET 类型,其中控制器实例是通过 Unity 注入的。所有的依赖,例如 DB Contexts 都在 Unity 配置文件中配置。

我的问题是,如何注入自定义 Attribute 类,它也使用 DB Context,即它有依赖关系?

这是控制器类的摘要:

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

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

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

提前感谢您的帮助。

N.

【问题讨论】:

    标签: unity-container


    【解决方案1】:

    您需要做的是让您的 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);
        }
    }
    

    在你的统一配置中添加简单的拦截扩展。

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

    将属性添加到您希望执行方面的接口方法中。

    [CustomAuthorize]
            ActionResult Index()
            {
        }
    

    希望这会有所帮助 干杯 鲁斯汀

    【讨论】:

      【解决方案2】:

      这不是完全不可能,但非常困难。

      问题在于属性对象本身是由 CLR 创建的(特别是反射 API,如果我理解正确的话),因此无法在其中获取容器来调用构造函数。而且您无法真正控制 何时 创建属性实例,因此您甚至无法保证您的容器是否会及时准备好。

      您可以编写一个自定义的 ActionInvoker 来遍历属性并在每个属性上调用 BuildUp,然后将其插入 MVC 管道。不过这很辛苦。

      Jimmy Bogard has a series on getting more DI into an MVC app,链接指向 Action Filters 上的特定主题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-13
        • 2012-07-30
        • 1970-01-01
        • 1970-01-01
        • 2012-05-03
        相关资源
        最近更新 更多