c# - 使用SimpleInjector基于泛型参数条件注册装饰器

标签 c# .net simple-injector

我有一个像这样的查询处理程序:

public class FooQueryHandler : IQueryHandler<FooQuery, FooResult>
{
      public FooResult Handle(FooQuery query) {
          // Query handled here.
      }
}

IQueryHandler接口(interface)定义为:

public interface IQueryHandler<TQuery, Result> : where TQuery : IQuery
{
    TResult Handle(TQuery query);
}

FooQuery定义为:

public class FooQuery : IAuthorizedQuery

哪里IAuthorizedQuery定义为:

public interface IAuthorizedQuery : IQuery

IQuery只是简单的界面。 FooResult只是一个简单的 DTO 对象。

IQueryHandler使用简单注入(inject)器注入(inject)并在容器中注册为:

container.Register(typeof(IQueryHandler<,>), assemblies);

问题

我想装饰IQueryHandler带有装饰器处理程序类。仅当查询对象(例如 FooQuery )实现 IAuthorizedQuery 时,才应有条件地应用此装饰器。这样可以进行一些基于角色的授权。

如果查询没有实现IAuthorizedQuery并且只有IQuery那么就不应该进行任何装饰。

处理程序需要如下所示:

 public AuthorizationQueryDecorator : IQueryHandler<TQuery, TResult> 
    where TQuery : IAuthorizedQuery 
 {
      public AuthorizationQueryDecorator(
            IQueryHandler<TQuery, TResult> handler,
            IAuthorizer<TQuery> authorizer)    
      {
           _authorizer = authorizer;
           _handler = handler;
      }

      private readonly IAuthorizer<TQuery> _authorizer;
      private readonly IQueryHandler<TQuery, TResult> handler;

      public TResult Handle(TQuery query) {
          if(!_authorizer.Authorise(query)) {
              // throw exception
          }
          else {
               handler.Handle(query);
          }
      }
 }

IAuthorizer<TQuery>接口(interface)只是一个带有 bool 方法的简单接口(interface) Authorise(TQuery query)如果可以基于某些基于角色的逻辑执行查询,则返回 true。

问题是我不确定如何使用 SimpleInjector 有条件地注册装饰器。

条件本质上是 IQueryHandler仅当 TQuery 对象实现 IAuthorizationQuery 时才应进行修饰。

我该怎么做?

目前我已经

 container.RegisterDecorator(
            typeof(IQueryHandler<,>),
            typeof(AuthorizationQueryDecorator<,>), \\\ PREDICATE?);

但我不知道应该指定什么谓词?

编辑

看来我遇到的问题是 IAuthorizer注册。

我有以下IAuthorizer实现:

public FooQueryAuthorizer() : IAuthorizer<FooQuery>

public NullQueryAuthorizer<TQuery, TResult> : IQueryAuthorizer<TQuery, TResult>
    where TQuery : IAuthorizedQuery<TResult> : IAuthorizer

SimpleInjector 注册IQueryAuthorizer是:

            container.RegisterConditional(
            typeof(IQueryAuthorizer<,>),
            typeof(NullQueryAuthorizer<,>),
            c => !c.Handled);

但是,NullQueryAuthorizer始终使用,无论是否存在特定实现(例如 FooQueryAuthorizer )。

我该如何解决这个问题?

最佳答案

您无需执行任何操作;简单注入(inject)器将自动为您应用通用类型约束。所以您的注册很简单:

container.RegisterDecorator(
    typeof(IQueryHandler<,>),
    typeof(AuthorizationQueryDecorator<,>));

文档 describes :

Simple Injector will automatically apply the registered type conditionally based on it generic type constraints

关于c# - 使用SimpleInjector基于泛型参数条件注册装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38224530/

相关文章:

c# - 你能在 ASP.net 2.0 中通过 CSS 或皮肤设置页面的标题吗

C#将程序编译成2个exe文件

c# - 为什么 Reflection 的 GetProperty() 或 GetField() 不是实例或扩展方法?

c# - SimpleInjector结合了WCF和“常规”注册

c# - .NET 中的数值不一致

c# - 解析正则表达式-(不够)

.net - Math.Floor() 和 Math.Truncate() 之间的区别

异步方法上的 C# Entity Framework 错误

c# - WebApi + 简单注入(inject)器 + OWIN

c# - 使用 SimpleInjector 的同一组单例进行多个 RegisterAll 注册