c# - 基于基本泛型类型调用正确的泛型接口(interface)实现

标签 c# dependency-injection simple-injector

这个问题集中在依赖注入(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/

相关文章:

c# - 在 C# 中将 JSON 作为字符串转换为 DataTable

c# - 检查 nullable 是否有值的正确方法

c# - 无法将类型“double”隐式转换为“System.Windows.Horizo​​ntalAlignment”。存在显式转换(您是否缺少类型转换?)

c# - SimpleInjector 在 .Net MVC 站点启动时抛出间歇性错误

c# - 依赖注入(inject)以解决与运行时数据的依赖关系

c# - 使用 MVVM 通过拖放重新排序 ItemsControl

java - ConstructorProperties注释不起作用

php - Laravel 5.1 错误的 Illuminate\Encryption\Encrypter 实例

java - 如何在 E4 应用程序中注入(inject)自定义单例 bean?

c# - Rebus with Simple Injector 重大变更