.Net Core后绑定动态实现工厂

时间:2017-11-21 03:13:54

标签: c# generics asp.net-core owin

我试图找出改变现有实施工厂的最佳方法,以便将我的信号器集线器中的事件动态注册到我的通用服务。

最初我打算将集线器注入服务,但我不想将它们连接起来或让客户端必须实现自己的集线器等,所以我决定创建一个订阅活动

但我不希望客户注册他们自己的工厂我想采用所有现有的工厂,并根据配置选项进行统一注册:

我有一个通用的crud服务,简化版看起来像这样

public interface IAsyncCRUDService<TDTO>
{
    Task<TDTO> Get(object[] id);
    Task<TDTO[]> GetList(IFilterResolver queryOptions);
    Task<TDTO> Create(TDTO skillDTO);
    Task<TDTO> Update(object[] id, TDTO skillDTO);
    Task<bool> Delete(object[] id);

    event EventHandler<TDTO> OnCreate;
    event EventHandler<TDTO> OnUpdate;
}

我试图想办法让配置使用自动将我的集线器事件注册到我的服务。

public interface ICRUDServiceHubBase<in T>
{
    Task Create(T entityDTO);
    Task Update(T entityDTO);
    Task Delete(object[] id);
}

在我的创业中,我想自动注册服务的事件。我希望这很容易和可配置

    //TODO: Move to extensions
    protected List<ServiceDescriptor> GetGenericServicesFromGenericTypeDefinition(IServiceCollection services, Type baseGenericTypeDefinition)
    {
        if(false == baseGenericTypeDefinition.IsGenericTypeDefinition)
        {
            throw new Exception($"Invalid Argument {nameof(baseGenericTypeDefinition)}");
        }

       return services.Where(s => s.ImplementationType.GetTypeInfo().IsGenericType)
            .Where(s => s.ImplementationType.GetTypeInfo().GetGenericTypeDefinition() == baseGenericTypeDefinition).ToList()

    }

    public EventHandler<TDTO> RegisterHubsCreate<TDTO>(IAsyncCRUDService<TDTO> service, ICRUDServiceHubBase<TDTO> hubService)
    {
        EventHandler<TDTO> handlerRef = (object obj, TDTO args) => { hubService.Create(args); };
        service.OnCreate += handlerRef;
        return handlerRef;
    }

    public void RegisterHubsEvents(IServiceCollection services)
    {
        var crudServiceDescriptors = this.GetGenericServicesFromGenericTypeDefinition(services, typeof(IAsyncCRUDService<>));

        foreach (var serviceDescriptor in crudServiceDescriptors)
        {
            var originalFunc = serviceDescriptor.ImplementationFactory;

            Func<IServiceProvider, object> HubsRegistered = (IServiceProvider provider) => {
                var serviceObj = originalFunc(provider);
                //TODO: since this is an instance you probably need to grab the interface type first
                //or you'll risk grrabbing the wrong parameter
                var dtoType = serviceObj.GetType().GetGenericArguments().First();
                var hubType = typeof(ICRUDServiceHubBase<>).MakeGenericType(dtoType);

                //Is this risky if the hub is transient will my object be disposed before the event fires?
                var hub = provider.GetService(hubType);

                var registerHubsDynamically = this.GetType().GetMethod("RegisterHubsCreate").MakeGenericMethod(dtoType);
                registerHubsDynamically.Invoke(this, new object[] { serviceObj, hub });

                return serviceObj;
            };

            serviceDescriptor.ImplementationFactory = HubsRegistered;

        }
    }

如何动态发送实现工厂,或者某些事件如何在调用实现工厂时注册?

0 个答案:

没有答案