Container.Register (Type, Assembly []) does not register common implementations

I have the following interfaces:

public interface IQuery<TResult>
{
}

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

One of my execution requests:

public class ApplyPermissionSetForUserAndPermissionTypeQuery<TQueryable, TEntity> : IQuery<TQueryable>
    where TQueryable : IQueryable<TEntity>
{
}

and handler:

public class ApplyPermissionSetForUserAndPermissionTypeHandler<TQueryable, TEntity> : IQueryHandler<ApplyPermissionSetForUserAndPermissionTypeQuery<TQueryable, TEntity>, TQueryable>
    where TQueryable : IQueryable<TEntity>
{
}

When creating a container, I call:

container.Register(typeof(IQueryHandler<,>), container.Settings.QueryHandlerAssemblies);

Which register of all types in the passed assembler passed and worked for all my other pens. One problem is largely different in that the request and the handler contain the generic type itself.

I currently logged a ResolveUnregisteredType event registered in the container, the following:

private void container_ResolveUnregisteredType(object sender, SimpleInjector.UnregisteredTypeEventArgs e)
{
    var serviceType = e.UnregisteredServiceType;

    if (serviceType.IsGenericType &&
        serviceType.GetGenericTypeDefinition() == typeof(IQueryHandler<,>))
    {
        var queryArg = serviceType.GetGenericArguments()[0];
        var resultArg = serviceType.GetGenericArguments()[1];

        if (queryArg.IsGenericType &&
            queryArg.GetGenericTypeDefinition() == typeof(ApplyPermissionSetForUserAndPermissionTypeQuery<,>))
        {
            var itemTypeArgument = queryArg.GetGenericArguments()[0];
            var entityTypeArgument = queryArg.GetGenericArguments()[1];
            if (itemTypeArgument != resultArg)
                return;

            Type typeToRegister;

            try
            {
                 typeToRegister = typeof(ApplyPermissionSetForUserAndPermissionTypeHandler<,>).MakeGenericType(itemTypeArgument, entityTypeArgument);
            }
            catch (ArgumentException)
            {
                // Thrown by MakeGenericType when the type constraints 
                // do not match. In this case, we don't have to register
                // anything and can bail out.
                return;
            }

            //Register a delegate which will return 
            e.Register(delegate () { return GetInstance(typeToRegister); });
            }
        }
    }

Which makes it work, so I know that you can register a type. This leads me to think that I'm missing something obvious, for example. the type is simply not registered using the container.Register method (typeof (IQueryHandler <,>), container.Settings.QueryHandlerAssemblies).

, , . . , :

container.Register(typeof(IQueryHandler<,>), typeof(IQueryHandler<ApplyPermissionSetForUserAndPermissionTypeQuery<,>,>))

, IQueryHandler <, > , , ?

+4
1

Container.Register(Type, Assembly[]) , -. , , , -.

, :

container.Register(typeof(IQueryHandler<,>), settings.QueryHandlerAssemblies);

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

, , , Container.GetTypesToRegister:

var queryHandlerTypes = container.GetTypesToRegister(typeof(IQueryHandler<,>), 
    settings.QueryHandlerAssemblies,
    new TypesToRegisterOptions { IncludeGenericTypeDefinitions = true });

container.Register(typeof(IQueryHandler<,>), 
    queryHandlerTypes.Where(t => !t.IsGenericTypeDefinition));

foreach (Type type in queryHandlerTypes.Where(t => t.IsGenericTypeDefinition))
{
    container.Register(typeof(IQueryHandler<,>), type);
}

, , Simple Injector , . , Simple Injector ( container.Verify()). , Register . , , :

foreach (Type type in queryHandlerTypes.Where(t => t.IsGenericTypeDefinition))
{
    container.RegisterConditional(typeof(IQueryHandler<,>), type, c => !c.Handled);
}
+3

Source: https://habr.com/ru/post/1617395/


All Articles