根据基本通用类型调用正确的通用接口实现
该问题集中在依赖注入和通用接口上。根据基本通用类型调用正确的通用接口实现
我的一个商业实体是身份证。可以有多种类型的ID卡,全部来自ICard
继承:
interface ICard
{
string CardId { get; }
}
class CardA : ICard
{
string CardId { get; set; }
string SomethingCardASpecific { get; set; }
}
class CardB : ICard
{
string CardId { get; set; }
bool SomethingCardBSpecific { get; set; }
}
我有一个CardFactory
,需要一个卡ID,并返回正确的卡类型(ICard
):
class CardFactory : ICardFactory // Trivial interface definition left out
{
ICard FromCardId(string cardId)
{
if (MatchesPatternA(cardId))
{
return new CardA { CardId = cardId /* ... */ }
}
else
{
return new CardB { CardId = cardId /* ... */ }
}
}
}
此外,我有另一个依赖关系,检查卡是否被授权执行某些操作。该逻辑依赖于卡片的类型,因此,通用的接口:
interface ICardAuthorization<TCard> where TCard : ICard
{
bool IsOperationXPermitted(TCard card);
bool IsOperationYPermitted(TCard card);
}
我有取决于ICardFactory
和ICardAuthorization
一个API控制器。一个动作收到cardId
,创建一张卡片,并检查它是否被授权采取行动X.控制器不关心两种卡片类型授权的处理方式不同,因此它应该取决于“基本”卡片上的操作类型(接口),即ICardAuthorization<ICard>
。
实际问题:
当然,我需要的ICardAuthorization
至少两种不同的实现,即
class CardAAuthorization : ICardAuthorization<CardA> { /* ... */ }
class CardBAuthorization : ICardAuthorization<CardB> { /* ... */ }
然而,使用上述的设计中,API需要依赖的接口上输入到ICard
:
class DelegatingCardAuthorization : ICardAuthorization<ICard> { /* ... */ }
这,反过来,d依靠两个“真正”的主力,ICardAuthorization<CardA>
和,并根据其方法接收的ICard
的类型调用正确的。
当然,在我的应用程序中,ICardAuthorization<TCard>
只是需要针对不同卡类型实施不同卡的几种接口之一。
在我看来,这似乎是一种相当健壮的方式来构建事物,但我不喜欢这样一个事实,即我需要委托实现来检查类型并将调用转发给其他实现。我可以忍受它,没问题,但是否有任何方法通过消除委托实现的需要来使这更优雅?(我正在使用SimpleInjector,如果重要的话)。
我想你不能完全删除委托实现的需要,因为选择基于卡类型的动作的逻辑应该驻留在某处。
然而,我提出的是与工厂同行。
创建CardAuthorizationFactory
这将根据传递给它的ICard
对象的类型返回适当的ICardAuthorization
实现者。为其他卡片操作创建任意数量的其他工厂。把所有这些作为单身人士加入IoC。
现在,当某些方法需要使用授权对某张卡片进行操作时,它应该查询AuthorizationFactory
以获取适合当前卡片对象的CardAuthorization
对象。工厂应该由IoC注入。它会满足你的需求吗?
您可以详细介绍一张卡创建后会发生什么?它是否直接返回到web api客户端?还是进一步传递到某种业务层? –
它不会返回给客户端,它仅用于业务层以识别用户。 – cmeeren