这个问题集中在依赖注入(inject)和通用接口(interface)上。
我的业务实体之一是身份证。身份证可以有多种类型,都继承自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):
interface ICardAuthorization<TCard> where TCard : ICard
{
bool IsOperationXPermitted(TCard card);
bool IsOperationYPermitted(TCard card);
}
我有一个依赖于 ICardFactory
的 API Controller 和 ICardAuthorization
.一个 Action 收到 cardId
,创建一张卡片,并检查它是否被授权执行操作 X。 Controller 不关心两种卡片类型的授权处理方式不同这一事实,因此它应该取决于“基本”卡片类型(接口(interface))上的操作,即 ICardAuthorization<ICard>
.
实际问题:
当然,我至少需要 ICardAuthorization
的两种不同实现方式, 即
class CardAAuthorization : ICardAuthorization<CardA> { /* ... */ }
class CardBAuthorization : ICardAuthorization<CardB> { /* ... */ }
但是,使用上述设计,API 需要依赖类型为 ICard
的接口(interface):
class DelegatingCardAuthorization : ICardAuthorization<ICard> { /* ... */ }
这又取决于两个“真正的”主力,ICardAuthorization<CardA>
和 ICardAuthorization<CardB>
, 并根据 ICard
的类型调用正确的一个它的方法接收。
当然,在我的应用程序中,ICardAuthorization<TCard>
只是需要针对不同卡类型进行不同实现的几个接口(interface)之一。
在我看来,这是一种相当稳健的结构化方式,但我不喜欢这样的事实,即我需要委托(delegate)实现来检查类型并将调用转发给其他实现。我可以接受它,没问题,但是是否有任何方法可以通过消除对委托(delegate)实现的需要来使它更优雅?(如果这很重要,我正在使用 SimpleInjector。)
最佳答案
我想您不能完全删除委派实现的需要,因为根据卡片类型选择操作的逻辑应该驻留在某个地方。
然而,我的建议是与工厂合作。
创建 CardAuthorizationFactory
,它将根据传递给它的 ICard
对象的类型返回适当的 ICardAuthorization
实现器。为其他卡片操作创建任意数量的其他工厂。将所有这些作为单例放入 IoC。
现在,当某些方法需要使用授权对卡片执行某些操作时,它应该在 AuthorizationFactory
中查询适合其当前拥有的卡片对象的 CardAuthorization
对象。工厂应该由 IoC 注入(inject)其中。它能满足您的需求吗?
关于c# - 基于基本泛型类型调用正确的泛型接口(interface)实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44197055/