c# - 逐步应用更好的设计

标签 c# configuration refactoring dependency-injection separation-of-concerns

为了获得一些良好的 OO 设计的实践经验,我决定尝试在遗留应用程序上应用关注点分离。

我决定我不喜欢这些调用分散在整个代码库中。

ConfigurationManager.AppSettings["key"]

虽然我之前已经通过编写一个辅助类来将这些调用封装到静态方法中来解决这个问题,但我认为这可能是一个更进一步的机会。

我意识到最终我应该以使用依赖注入(inject)为目标,并且始终“编码到接口(interface)”。但我不想迈出看似太大的一步。与此同时,我想朝着这个最终目标迈出更小的一步。

Can anyone enumerate the steps they would recommend?

下面是一些我想到的:

  • 让客户端代码依赖于接口(interface)而非具体实现

  • 手动注入(inject)依赖到一个 通过构造函数或属性接口(interface)?

  • 在努力之前 选择和应用 IoC 容器 我如何保存代码 运行?

  • 为了满足默认的依赖 任何需要的类的构造函数 配置值可以使用工厂 (使用静态 CreateObject() 方法)?

我肯定仍然对工厂有具体的依赖吗?...

我已经深入研究了 Michael Feathers' book所以我知道我需要引入接缝,但我很难知道我何时引入了足够多或太多!

更新

想象一下,客户端调用 WidgetLoader 上的方法并将所需的依赖项(例如 IConfigReader)传递给它

WidgetLoader 读取配置以找出要加载的 Widget 并要求 WidgetFactory 依次创建每个 Widget

WidgetFactory 读取配置以知道默认情况下将 Widget 置于什么状态

WidgetFactory 委托(delegate) WidgetRepository 进行数据访问,WidgetRepository 读取配置以决定它应该记录哪些诊断信息

In each case above should the IConfigReader be passed like a hot potato between each member in the call chain?

Is a Factory the answer?

澄清以下一些评论:

我的主要目标是逐渐将一些应用程序设置从配置文件中迁移出来,并以某种其他形式持久化。虽然我意识到通过注入(inject)的依赖项我可以 Extract and Override为了获得一些单元测试的好处,我主要关心的不是测试太多,而是封装得足够多,以至于开始不知道设置实际保存在哪里。

最佳答案

重构遗留代码库时,您希望随着时间的推移迭代地进行小的更改。这是一种方法:

  • 使用获取应用设置的方法(即 GetAppSettingString( string key ))创建一个新的静态类(即 MyConfigManager)

  • 全局搜索并替换“ConfigurationManager.AppSettings["key"] 并将实例替换为“MyConfigManager.GetAppSettingsString("key")”

  • 测试和 checkin

现在您对 ConfigurationManager 的依赖位于一处。您可以将您的设置存储在数据库中或任何地方,而无需更改大量代码。不利的一面是您仍然具有静态依赖性。

下一步是将 MyConfigManager 更改为常规实例类,并将其注入(inject)到使用它的类中。这里最好的方法是逐步进行。

  • 在静态类旁边创建一个实例类(和一个接口(interface))。

  • 既然你已经拥有了这两者,你可以慢慢地重构 using 类,直到它们都在使用实例类。将实例注入(inject)构造函数(使用接口(interface))。如果有很多用法,请不要尝试大爆炸 checkin 。随着时间的推移,慢慢地、小心地做。

  • 然后只删除静态类。

关于c# - 逐步应用更好的设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1888719/

相关文章:

c# - HttpClient不报告从Web API返回的异常

c# - ConcurrentDictionary 是 SortedList 的 "concurrent"版本吗?

javascript - 如何使用 QueryString 获取 TextBox 的文本并将其从 JavaScript 发送到代码隐藏

python - 如何将 IPython 历史记录到文本文件?

php -/etc/php5/conf.d 文件夹中的 .ini 文件有什么用?

c# - 如何使某些 ListView 项目 'greyed-out' 且不可选择?

azure - 为什么无法在我的 azure 函数配置中输入 blob 存储帐户的连接字符串?

c# - 重构异步方法

java - Web服务项目的重构

java - 如何解析可选 URL 参数