C# 不带服务定位器的CQRS调度器

C# 不带服务定位器的CQRS调度器,c#,asp.net,asp.net-core,cqrs,C#,Asp.net,Asp.net Core,Cqrs,我正在基于现有的Asp.Net 4.5解决方案创建一个新的Asp.Net核心解决方案 当前解决方案使用Microsoft Unity容器,并且基础结构具有对服务定位器的引用 我想摆脱服务定位器,避免在我的新基础设施中引用特定的DI容器 我遇到了一个问题,即如何在没有任何DI容器依赖项的情况下替换当前的命令/查询/事件调度器 这是我的调度课 public class Dispatcher : IDispatcher { private const string HandleMethodNa

我正在基于现有的Asp.Net 4.5解决方案创建一个新的Asp.Net核心解决方案

当前解决方案使用Microsoft Unity容器,并且基础结构具有对服务定位器的引用

我想摆脱服务定位器,避免在我的新基础设施中引用特定的DI容器

我遇到了一个问题,即如何在没有任何DI容器依赖项的情况下替换当前的命令/查询/事件调度器

这是我的调度课

public class Dispatcher : IDispatcher
{
    private const string HandleMethodName = "Handle";

    public TResponse Request<TResponse>(IQuery<TResponse> query)
    {
        Type queryType = query.GetType();

        // used for when OperationResult<object> was used
        Type operationResultTrueReturnType = typeof(TResponse);
        if (operationResultTrueReturnType == typeof(object))
        {
            operationResultTrueReturnType = queryType.GetInterface(typeof(IQuery<>).Name).GenericTypeArguments[0];
        }

        Type handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), operationResultTrueReturnType);
        return ExecuteHandler<TResponse>(handlerType, query, queryType);
    }

    public OperationResult Submit(ICommand command)
    {
        Type commandType = command.GetType();

        var baseTypeAttribute = (CommandBaseTypeAttribute)commandType.GetCustomAttributes(typeof(CommandBaseTypeAttribute), false).FirstOrDefault();
        if (baseTypeAttribute != null)
            commandType = baseTypeAttribute.BaseType;

        try
        {
            Type handlerType = typeof(ICommandHandler<>).MakeGenericType(commandType);
            return ExecuteHandler<OperationResult>(handlerType, command, commandType);
        }
        catch (InvalidOperationException ex)
        {
            return new OperationResult(OperationResultStatus.Failure, ex.Message);
        }
    }

    public OperationResult<TResult> Submit<TResult>(ICommand<TResult> command)
    {
        Type commandType = command.GetType();

        var baseTypeAttribute = (CommandBaseTypeAttribute)commandType.GetCustomAttributes(typeof(CommandBaseTypeAttribute), false).FirstOrDefault();
        if (baseTypeAttribute != null)
            commandType = baseTypeAttribute.BaseType;

        try
        {
            Type handlerType = typeof(ICommandHandler<,>).MakeGenericType(commandType, typeof(TResult));
            return ExecuteHandler<OperationResult<TResult>>(handlerType, command, commandType);
        }
        catch (InvalidOperationException ex)
        {
            return new OperationResult<TResult>(OperationResultStatus.Failure, default(TResult), ex.Message);
        }
    }

    public void Raise(IDomainEvent domainEvent)
    {
        Type domainEventType = domainEvent.GetType();

        try
        {
            Type handlerType = typeof(ICommandHandler<>).MakeGenericType(domainEventType);
            ExecuteHandler(handlerType, domainEvent, domainEventType);
        }
        catch (InvalidOperationException)
        {

        }
    }

    private static void ExecuteHandler(Type handlerType, object argument, Type argumentType)
    {
        object handler = ServiceLocator.Current.GetInstance(handlerType);

        if (handler == null)
            throw new ConfigurationErrorsException("Handler not registered for type " + argumentType.Name);

        try
        {
            MethodInfo handleMethod = handlerType.GetMethod(HandleMethodName, new[] { argumentType });
            handleMethod.Invoke(handler, new[] { argument });
        }
        catch (TargetInvocationException ex)
        {
            if (ex.InnerException != null)
                throw ex.InnerException;
            throw;
        }
    }

    private static TReturnValue ExecuteHandler<TReturnValue>(Type handlerType, object argument, Type argumentType)
    {
        object handler = ServiceLocator.Current.GetInstance(handlerType);

        if (handler == null)
            throw new ConfigurationErrorsException("Handler not registered for type " + argumentType.Name);

        try
        {
            MethodInfo handleMethod = handlerType.GetMethod(HandleMethodName, new[] { argumentType });
            return (TReturnValue)handleMethod.Invoke(handler, new[] { argument });
        }
        catch (TargetInvocationException ex)
        {
            if (ex.InnerException != null)
                throw ex.InnerException;
            throw;
        }
    }
}
公共类调度程序:IDispatcher
{
私有常量字符串HandleMethodName=“Handle”;
公共响应请求(IQuery查询)
{
类型queryType=query.GetType();
//在使用OperationResult时用于
Type operationResultTrueReturnType=typeof(t响应);
if(operationResultTrueReturnType==typeof(对象))
{
operationResultTrueReturnType=queryType.GetInterface(typeof(IQuery).Name).GenericTypeArguments[0];
}
Type handlerType=typeof(IQueryHandler).MakeGenericType(query.GetType(),operationResultTrueReturnType);
返回ExecuteHandler(handlerType、query、queryType);
}
公共操作结果提交(ICommand命令)
{
类型commandType=command.GetType();
var baseTypeAttribute=(CommandBaseTypeAttribute)commandType.GetCustomAttributes(typeof(CommandBaseTypeAttribute),false).FirstOrDefault();
if(baseTypeAttribute!=null)
commandType=baseTypeAttribute.BaseType;
尝试
{
类型handlerType=typeof(ICommandHandler);
返回ExecuteHandler(handlerType、command、commandType);
}
捕获(无效操作异常ex)
{
返回新的OperationResult(OperationResultStatus.Failure,ex.Message);
}
}
公共操作结果提交(ICommand命令)
{
类型commandType=command.GetType();
var baseTypeAttribute=(CommandBaseTypeAttribute)commandType.GetCustomAttributes(typeof(CommandBaseTypeAttribute),false).FirstOrDefault();
if(baseTypeAttribute!=null)
commandType=baseTypeAttribute.BaseType;
尝试
{
Type handlerType=typeof(ICommandHandler)。MakeGenericType(commandType,typeof(TResult));
返回ExecuteHandler(handlerType、command、commandType);
}
捕获(无效操作异常ex)
{
返回新的OperationResult(OperationResultStatus.Failure,默认值(TResult),例如Message);
}
}
公共无效引发(IDomainEvent domainEvent)
{
类型domainEventType=domainEvent.GetType();
尝试
{
类型handlerType=typeof(ICommandHandler)。MakeGenericType(domainEventType);
ExecuteHandler(handlerType、domainEvent、domainEventType);
}
捕获(无效操作异常)
{
}
}
私有静态void ExecuteHandler(类型handlerType、对象参数、类型argumentType)
{
对象处理程序=ServiceLocator.Current.GetInstance(handlerType);
if(handler==null)
抛出新的ConfigurationErrorsException(“未为类型“+argumentType.Name”注册处理程序);
尝试
{
MethodInfo handleMethod=handlerType.GetMethod(HandleMethodName,新[]{argumentType});
调用(处理程序,新[]{argument});
}
捕获(目标异常)
{
if(例如InnerException!=null)
抛出ex.InnerException;
投掷;
}
}
私有静态TReturnValue ExecuteHandler(类型handlerType、对象参数、类型argumentType)
{
对象处理程序=ServiceLocator.Current.GetInstance(handlerType);
if(handler==null)
抛出新的ConfigurationErrorsException(“未为类型“+argumentType.Name”注册处理程序);
尝试
{
MethodInfo handleMethod=handlerType.GetMethod(HandleMethodName,新[]{argumentType});
return(TReturnValue)handleMethod.Invoke(handler,new[]{argument});
}
捕获(目标异常)
{
if(例如InnerException!=null)
抛出ex.InnerException;
投掷;
}
}
}
ExecuteHandler具有ServiceLocator调用


如果不使用它,我如何处理这个问题?

我喜欢评论中提供的建议。如果您想要抽象出服务定位器,那么让调度器显式地依赖于将用于执行解析的抽象服务提供者(如
IServiceProvider

public class Dispatcher : IDispatcher {
    private readonly IServiceProvider serviceProvider;

    public Dispatcher (IServiceProvider serviceProvider) {
        this.serviceProvider = serviceProvider;
    }

    //...other code removed for brevity

    private object GetService(Type serviceType) {
        return serviceProvider.GetService(serviceType);
    }

    private void ExecuteHandler(Type handlerType, object argument, Type argumentType) {
        object handler = GetService(handlerType);

        if (handler == null)
            throw new ConfigurationErrorsException("Handler not registered for type " + argumentType.Name);

        try {
            MethodInfo handleMethod = handlerType.GetMethod(HandleMethodName, new[] { argumentType });
            handleMethod.Invoke(handler, new[] { argument });
        } catch (TargetInvocationException ex) {
            if (ex.InnerException != null)
                throw ex.InnerException;
            throw;
        }
    }

    private TReturnValue ExecuteHandler<TReturnValue>(Type handlerType, object argument, Type argumentType) {
        object handler = GetService(handlerType);

        if (handler == null)
            throw new ConfigurationErrorsException("Handler not registered for type " + argumentType.Name);

        try {
            MethodInfo handleMethod = handlerType.GetMethod(HandleMethodName, new[] { argumentType });
            return (TReturnValue)handleMethod.Invoke(handler, new[] { argument });
        } catch (TargetInvocationException ex) {
            if (ex.InnerException != null)
                throw ex.InnerException;
            throw;
        }
    }    
}
公共类调度程序:IDispatcher{
私有只读服务器ViceProvider服务提供商;
公共调度程序(IServiceProvider服务提供程序){
this.serviceProvider=serviceProvider;
}
//…为简洁起见,删除了其他代码
私有对象GetService(类型serviceType){
返回serviceProvider.GetService(serviceType);
}
私有void ExecuteHandler(类型handlerType、对象参数、类型argumentType){
对象处理程序=GetService(handlerType);
if(handler==null)
抛出新的ConfigurationErrorsException(“未为类型“+argumentType.Name”注册处理程序);
试一试{
MethodInfo handleMethod=handlerType.GetMethod(HandleMethodName,新[]{argumentType});
调用(处理程序,新[]{argument});
}捕获(目标异常){
if(例如InnerException!=null)
抛出ex.InnerException;
投掷;
}
}
私有TReturnValue ExecuteHandler(类型handlerType、对象参数、类型argumentType){
对象处理程序=GetService(handlerType);
if(handler==null)
抛出新的ConfigurationErrorsException(“未注册处理程序
public class Dispatcher : IDispatcher
{
    private const string HandleMethodName = "Handle";

    private readonly IServiceProvider _serviceProvider;

    public Dispatcher(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public TResponse Request<TResponse>(IQuery<TResponse> query)
    {
        Type queryType = query.GetType();

        // used for when OperationResult<object> was used
        Type operationResultTrueReturnType = typeof(TResponse);
        if (operationResultTrueReturnType == typeof(object))
        {
            operationResultTrueReturnType = queryType.GetInterface(typeof(IQuery<>).Name).GenericTypeArguments[0];
        }

        Type handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), operationResultTrueReturnType);
        return ExecuteHandler<TResponse>(handlerType, query, queryType);
    }

    public OperationResult Submit(ICommand command)
    {
        Type commandType = command.GetType();

        var baseTypeAttribute = (CommandBaseTypeAttribute)commandType.GetCustomAttributes(typeof(CommandBaseTypeAttribute), false).FirstOrDefault();
        if (baseTypeAttribute != null)
            commandType = baseTypeAttribute.BaseType;

        try
        {
            Type handlerType = typeof(ICommandHandler<>).MakeGenericType(commandType);
            return ExecuteHandler<OperationResult>(handlerType, command, commandType);
        }
        catch (InvalidOperationException ex)
        {
            return new OperationResult(OperationResultStatus.Failure, ex.Message);
        }
    }

    public OperationResult<TResult> Submit<TResult>(ICommand<TResult> command)
    {
        Type commandType = command.GetType();

        var baseTypeAttribute = (CommandBaseTypeAttribute)commandType.GetCustomAttributes(typeof(CommandBaseTypeAttribute), false).FirstOrDefault();
        if (baseTypeAttribute != null)
            commandType = baseTypeAttribute.BaseType;

        try
        {
            Type handlerType = typeof(ICommandHandler<,>).MakeGenericType(commandType, typeof(TResult));
            return ExecuteHandler<OperationResult<TResult>>(handlerType, command, commandType);
        }
        catch (InvalidOperationException ex)
        {
            return new OperationResult<TResult>(OperationResultStatus.Failure, default(TResult), ex.Message);
        }
    }

    private TReturnValue ExecuteHandler<TReturnValue>(Type handlerType, object argument, Type argumentType)
    {
        object handler = _serviceProvider.GetService(handlerType);

        if (handler == null)
            throw new ArgumentException("Handler not registered for type " + argumentType.Name);

        try
        {
            MethodInfo handleMethod = handlerType.GetMethod(HandleMethodName, new[] { argumentType });
            return (TReturnValue)handleMethod.Invoke(handler, new[] { argument });
        }
        catch (TargetInvocationException ex)
        {
            if (ex.InnerException != null)
                throw ex.InnerException;
            throw;
        }
    }
}
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ResolutionDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddMvc();

    // Domain Event Handlers
    services.AddTransient<IEventHandler<RequestCreatedEvent>, RequestCreatedHandler>();

    // Domain Event Dispatcher
    services.AddSingleton<IDomainEventDispatcher, DomainEventDispatcher>();

    // Units of Work
    services.AddTransient<IResolutionUnitOfWork, ResolutionUnitOfWork>();

    // Commands and Queries
    services.AddTransient<ICommandHandler<CreateRequestCommand, Guid>, CreateRequestHandler>();

    // Command and Query Dispatcher
    services.AddSingleton<IDispatcher, Dispatcher>();
}