StructureMap注册通用类型以在注入的数组集合中使用它们 [英] StructureMap registering generic types for using them in injected array collection

查看:68
本文介绍了StructureMap注册通用类型以在注入的数组集合中使用它们的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用StructureMap进行依赖项注入,想注册我的通用类IDefaultRequestHandler的所有可能类型,所以它们是 注入IDefaultRequestHandler []集合中,在这里我可以根据策略模式选择要初始化的对象.

I am using StructureMap for dependency injection, and I would like to register all possible types of my generic class IDefaultRequestHandler, so they are injected in IDefaultRequestHandler[] collection, where I can choose which object to initialize based on strategy pattern.

我拥有以下
通用类:

I have following
Generic class:

public interface IDefaultRequestHandler<T> where T : CreditCardRequestBaseModel
{
    SubCentreEnum CentreKey { get; }
    bool IsSmartSearch { get; }
    T CreateDefault(Centre centre);
    T GetDefaultFilters(Centre centre);
    void Validate(T request, Centre centre);
    List<KeyValuePair<string, SortDirection>> SetSortingRules(string sortKey);
}

public class RequestDefaultInitializer : IDefaultRequestHandler<BalanceTransferRequestAmel> { public SubCentreEnum CentreKey => SubCentreEnum.BalanceTransfers; public bool IsSmartSearch => false; private readonly IRuleSorterStrategy _ruleSorterStrategy; public RequestDefaultInitializer(IRuleSorterStrategy ruleSorterStrategy) { _ruleSorterStrategy = ruleSorterStrategy; } public BalanceTransferRequestAmel CreateDefault(Centre centre) { throw new NotImplementedException(); } public BalanceTransferRequestAmel GetDefaultFilters(Centre centre) { throw new NotImplementedException(); } public void Validate(BalanceTransferRequestAmel request, Centre centre) { throw new NotImplementedException(); } public List<KeyValuePair<string, SortDirection>> SetSortingRules(string sortKey) { throw new NotImplementedException(); } }

然后,我正在使用策略来选择适当的实现:

Then I am using strategy to select proper implementation:

public interface IRequestManagerStrategy { T CreateDefault<T>(Centre centre, SubCentreEnum centreKey, bool isSmartSearch) where T : CreditCardRequestBaseModel; void Validate<T>(T request, Centre centre, SubCentreEnum centreKey, bool isSmartSearch) where T : CreditCardRequestBaseModel; } public class RequestManagerStrategy : IRequestManagerStrategy { private readonly IDefaultRequestHandler<CreditCardRequestBaseModel>[] _defaultRequestHandlers; public RequestManagerStrategy(IDefaultRequestHandler<CreditCardRequestBaseModel>[] defaultRequestHandlers) { _defaultRequestHandlers = defaultRequestHandlers; } public T CreateDefault<T>(Centre centre, SubCentreEnum centreKey, bool isSmartSearch) where T : CreditCardRequestBaseModel { return _defaultRequestHandlers.FirstOrDefault(x => x.CentreKey == centreKey && x.IsSmartSearch == isSmartSearch).CreateDefault(centre) as T; } public void Validate<T>(T request, Centre centre, SubCentreEnum centreKey, bool isSmartSearch) where T : CreditCardRequestBaseModel { _defaultRequestHandlers.FirstOrDefault(x => x.CentreKey == centreKey && x.IsSmartSearch == isSmartSearch).Validate(request, centre); } }

My StructureMap dependency set up:

 Scan(o =>
    {
        o.AddAllTypesOf<IRuleSorter>();
        //o.AddAllTypesOf(typeof(IDefaultRequestHandler<>));
            o.ConnectImplementationsToTypesClosing(typeof(IDefaultRequestHandler<>));
        o.LookForRegistries();
        o.AddAllTypesOf<AutoMapper.Profile>();
        o.WithDefaultConventions();
    });

Problem is that there is nothing in the private readonly IDefaultRequestHandler[] _defaultRequestHandlers; inside of RequestManagerStrategy since it is not matching types I think. I think I am messing up something with generic implementation.

Problem is that there is nothing in the private readonly IDefaultRequestHandler[] _defaultRequestHandlers; inside of RequestManagerStrategy since it is not matching types I think. I think I am messing up something with generic implementation.

If I change type from CreditCardRequestBaseModel to BalanceTransferRequestAmel I have stuff populated into the list, but I want to have all types inherited from CreditCardRequestBaseModel in that array, that's the purpose I am doing generic implementation.

If I change type from CreditCardRequestBaseModel to BalanceTransferRequestAmel I have stuff populated into the list, but I want to have all types inherited from CreditCardRequestBaseModel in that array, that's the purpose I am doing generic implementation.

推荐答案

Hi Benzemalo,

Hi Benzemalo,

The reason is that dependency injection doesn't support Generic Covariant. I suggest you define a non-generic type which let IDefaultRequestHandler<T> derives from.

The reason is that dependency injection doesn't support Generic Covariant. I suggest you define a non-generic type which let IDefaultRequestHandler<T> derives from.

public interface IDefaultRequestHandler
{

}

public interface IDefaultRequestHandler<T> : IDefaultRequestHandler where T : CreditCardRequestBaseModel
{

}

Then you could use IDefaultRequestHandler in your RequestManagerStrategy class.

Then you could use IDefaultRequestHandler in your RequestManagerStrategy class.

private readonly IDefaultRequestHandler[] _defaultRequestHandlers;

public RequestManagerStrategy(IDefaultRequestHandler[] defaultRequestHandlers)
{
    _defaultRequestHandlers = defaultRequestHandlers;
}

最好的问候,
Li Wang

Best Regards,
Li Wang


这篇关于StructureMap注册通用类型以在注入的数组集合中使用它们的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆