ASP.NET MVC ContactsManager 教程中是否有解决依赖注入循环问题的好/正确方法?

2023-12-15

如果您不知道我在说什么,请查看教程并尝试自己添加依赖注入,或者尝试我对问题的解释。

Note:此问题不属于 ASP.NET 原始教程的范围。本教程仅表明所使用的模式是依赖注入友好的。

问题基本上是控制器、ModelStateWrapper 和 ContactManagerService 之间存在依赖循环。

  1. ContactController 构造函数采用 IContactManagerService。
  2. Contact Manager Service 构造函数采用 Contact Manager 存储库(不重要)和一个 IValidationDictionary(ModelStateWrapper 实现).
  3. ModelStateWrapper 构造函数采用 ModelStateDictionary(这是控制器上名为“ModelState”的属性).

所以依赖循环是这样的:Controller > Service > ModelStateWrapper > Controller

如果您尝试为此添加依赖注入,它将失败。所以我的问题是;我该怎么办?其他人已经发布了这个问题,但答案很少,各不相同,而且看起来都有点“hack-ish”。

我当前的解决方案是从 IService 构造函数中删除 IModelStateWrapper 并添加一个 Initialize 方法,如下所示:

public class ContactController : Controller
{
    private readonly IContactService _contactService;

    public ContactController(IContactService contactService)
    {
        _contactService = contactService;
        contactService.Initialize(new ModelStateWrapper(ModelState));
    }

    //Class implementation...
}

public class ContactService : IContactService
{
    private IValidationDictionary _validationDictionary;
    private readonly IContactRepository _contactRepository;

    public ContactService(IContactRepository contactRepository)
    {
        _contactRepository = contactRepository;
    }

    private void Initialize(IValidationDictionary validationDictionary)
    {
        if(validationDictionary == null)
            throw new ArgumentNullException("validationDictionary");

        _validationDictionary = validationDictionary;
    }

    //Class implementation...
}

public class ModelStateWrapper : IValidationDictionary
{
    private readonly ModelStateDictionary _modelState;

    public ModelStateWrapper(ModelStateDictionary modelState)
    {
        _modelState = modelState;
    }

    //Class implementation...
}

通过这个构造,我可以像这样配置我的统一容器:

public static void ConfigureUnityContainer()
{
    IUnityContainer container = new UnityContainer();

    // Registrations
    container.RegisterTypeInHttpRequestLifetime<IContactRepository, EntityContactRepository>();
    container.RegisterTypeInHttpRequestLifetime<IContactService, ContactService>();

    ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container));
}

不幸的是,这意味着必须调用服务上的“Initialize”方法manually由控制器构造函数。有没有更好的办法?也许我在哪里以某种方式将 IValidationDictionary 包含在我的统一配置中?我应该切换到另一个 DI 容器吗?我错过了什么吗?


作为一般考虑,循环依赖表明存在设计缺陷 - 我想我可以安全地说这一点,因为您不是代码的原始作者:)

我不认为初始化方法是一个好的解决方案。除非您正在处理加载项场景(您不是),否则方法注入不是正确的解决方案。您几乎已经弄清楚了这一点,因为您发现需要手动调用它并不令人满意,因为您的 DI 容器不能。

除非我完全错误,否则 ContactController 在调用其 Action 方法之前不需要 IValidationDictionary 实例?

如果这是真的,最简单的解决方案可能是定义一个 IValidationDictionaryFactory 接口并让 ContactController 构造函数采用该接口的实例。

这个接口可以这样定义:

public interface IValidationDictionaryFactory
{
    IValidationDictionary Create(Controller controller);
}

控制器上任何需要 IValidationDictionary 实例的 Action 方法都可以调用 Create 方法来获取该实例。

默认实现如下所示:

public class DefaultValidationDictionaryFactory : IValidationDictionaryFactory
{
    public IValidationDictionary Create(Controller controller)
    {
        return controller.ModelState;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ASP.NET MVC ContactsManager 教程中是否有解决依赖注入循环问题的好/正确方法? 的相关文章

随机推荐

  • 什么允许函数在返回参数时隐式取消引用参数?

    在读的时候如何借用可变引用而不将其传递给函数 OP 的功能如下 fn deref lt a b a T gt t a mut b mut T gt a mut T t 这对我来说很有意义 然而 他们也指出 正文中的显式取消引用 不需要 fn
  • Java中删除注释的脚本

    有谁知道如何 或过程 在构建时从 Java 类文件中删除注释 当使用 Ant 构建项目时 我想对项目中的特定包执行此操作 任何 ANT 脚本或一些自定义代码最受欢迎 编译后没有任何注释 class file
  • 如何使用 python asyncio 编写 Consumer.Producer 代码?

    我的Python版本是3 6 1 我写了一些东西来使用 Python asyncio 实现消费者 生产者模型 但它并没有按预期工作 四个活动均已创建 但没有任何打印导出 async def consumer queue id while T
  • 使用管道时出现“文件名、目录名或卷标语法不正确。”

    当我在我的机器上运行以下命令 或任何带有管道 的命令 时 目录 findstr 目录 我收到以下消息 文件名 目录名或卷标语法不正确 单独运行 dir 命令或 findstr 命令效果很好 卷标是 volC 盘中的卷是 OSDisk卷序列号
  • wpf 中自定义镀铬 Windows

    我尝试使用 WindowStyle None 和AllowsTransparency True 在 wpf 中创建自定义镀铬窗口 但是 当我最大化窗口时 它会覆盖整个屏幕 并超出其边缘 它还会隐藏我的窗口底部的 Windows 栏 屏幕 就
  • 枚举器的行为会根据我们引用它的方式而变化吗?

    将列表枚举器的引用包装在类中似乎会改变其行为 匿名类的示例 public static void Main var list new List
  • 如何在swift中重载赋值运算符

    我想重写 CGFloat 的 运算符 如下所示 func inout left CGFloat right Float left CGFloat right 所以我可以执行以下操作 var A CGFloat 1 var B Float 2
  • SQL Server:计算每月总销售额,包括空月

    我正在尝试计算一个月内产品的总销售额 但我希望它包括任何 空 月份 没有销售额 并且仅选择最近 12 个月 这是我到目前为止的代码 declare ProductNo int set ProductNo 1234 SELECT YEAR o
  • 如何向 MySQL 表添加“权重”并根据这些权重选择随机值?

    我想创建一个表 每行都包含某种权重 然后我想选择概率等于 该行的权重 所有行的权重 的随机值 例如 如果有 5 行 权重为 1000 中的 1 2 3 4 5 我会得到大约 1 15 1000 67 倍第一行 依此类推 该表需要手动填写 然
  • 使用PowerShell查找字符串中的差异

    所以我正在使用 Compare Object 它对于比较文件效果很好 但如果只是字符串呢 有没有办法找出字符串之间的差异 CompareTo 擅长报告存在差异 但不报告差异是什么 例如 PS gt a PowerShell rocks PS
  • Numpy 结构化数组无法完成基本 numpy 操作

    我想操纵namednumpy 数组 加 乘 连接 我定义了结构化数组 types name1 int name2 float a np array 2 3 3 dtype types b np array 4 5 35 dtype type
  • pandas 有没有办法从系列中删除重复项?

    我有一个数据框在 标签 列中有一些用逗号分隔的重复标签 有没有办法从系列中删除重复的字符串 我希望 400 的输出只有博物馆 饮酒 购物 我无法用逗号分割并删除它们 因为该系列中有一些标签具有相似的单词 例如 博物馆 艺术博物馆 购物 因此
  • 下载已部署的GAE应用程序的源代码

    如果我的硬盘上丢失了已部署应用程序的源代码 我可以下载该应用程序的源代码吗 我浏览了应用程序仪表板 但找不到任何选项来检查它 不 您不能 并且没有计划提供此类功能 抱歉 下次考虑投资 VCS 和备份
  • 如何访问AWS Lambda中的标头?

    我正在使用 AWS Api 网关 我已经使用 API Gateway 创建了资源和方法 我创建了 Lambda 函数 用于生成 json 格式的签名 URL 以通过 CloudFront 访问 s3 存储桶 当我使用 GET 方法调用 la
  • CMYK 值作为背景颜色

    我必须使用 RGB 值设置 div 的背景颜色 我能做到这一点 div style width 100px height 100px background color rgb 255 0 0 div 现在 由于我也有 CMYK 0 1 0
  • 在 Active Collab API 中获取分页结果

    我刚刚发现你可以通过传入 page 参数来通过 api 获取分页结果 如下所示 projects client gt get projects 147 time records page 3 gt getJson 有没有办法知道一个项目有多
  • 动态改变jButton图标

    我有一个程序可以检测某些机器何时在线 并创建一个带有绿色 在线 图标的按钮来显示这一点 我想添加功能来定期检查这台机器是否仍然在线 如果不是 请将图标更改为我已经定义的 离线 图标 我知道如何设置图标 但我不知道如何做到这一点 一旦按钮已经
  • 用于重新启动 Raspberry Pi 的 Python 脚本

    我想我想要的是直接的 在 23 小时 59 分钟后重新启动我的 Raspberry Pi 的 Python 脚本 我尝试执行此操作而不是使用 cron 作业设置时间的原因是 Pi 没有用于时钟的板载电池 所以我不在乎时间是什么 如果连接到互
  • 无法通过 Delphi 2010 和 Indy 10.5.5 使用与 Office365 的安全 SMTP 连接

    任何人都可以诊断我使用 Delphi 2010 和 Indy 10 5 5 连接到 smtp office365 com 的失败吗 我已经阅读了 Indy 专家 Remy Lebeau 在这个问题中提供的代码示例 将 INDY 10 SMT
  • ASP.NET MVC ContactsManager 教程中是否有解决依赖注入循环问题的好/正确方法?

    如果您不知道我在说什么 请查看教程并尝试自己添加依赖注入 或者尝试我对问题的解释 Note 此问题不属于 ASP NET 原始教程的范围 本教程仅表明所使用的模式是依赖注入友好的 问题基本上是控制器 ModelStateWrapper 和