Unity - 注入属性类

发布于 2024-10-10 15:02:02 字数 553 浏览 2 评论 0原文

我想知道是否有人知道是否可以通过 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。

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 MVC2 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

缺⑴份安定 2024-10-17 15:02:02

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

希望这有帮助
干杯
拉斯廷

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

盛装女皇 2024-10-17 15:02:02

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

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

您可以编写一个自定义 ActionInvoker,它会旋转属性并对每个属性调用 BuildUp,然后将其插入 MVC 管道。虽然这很辛苦。

吉米Bogard 有一个关于将更多 DI 引入 MVC 应用程序的系列文章,该链接指向 Action Filters 的特定主题。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文