2012-01-30 167 views
0

我有一个Autofac DI容器,并使用构造函数注入将配置设置注入到我的SampleClass中。配置管理器类创建为singleInstance,因此使用相同的单个实例。抛出异常构造函数注入 - AutoFac依赖注入

public ConfigurationManager() 
{ 
    // Load the configuration settings 
    GetConfigurationSettings(); 
} 

public SampleClass(IConfigurationManager configurationManager) 
{ 
    _configurationManager = configurationManager; 
} 

我从配置管理器的构造函数中的App.config文件加载配置设置。我的问题是我也验证配置设置,如果他们不在App.config文件中引发异常,这会导致程序崩溃。这意味着我无法处理异常并返回响应。

我这样做是错误的吗?是否有更好的方法来加载配置设置还是有办法处理抛出的异常。

编辑

ConfigurationManager configurationManager = new ConfigurationManager(); 
configurationManager.GetConfigurationSettings(); 
//Try catch around for the exception thrown if config settings fail 

//Register the instance above with autofac 
builder.Register(configurationManager()).As<IConfigurationManager>().SingleInstance(); 


//Old way of registering the configurationManager 
builder.Register(c => new ConfigurationManager()).As<IConfigurationManager>().SingleInstance(); 
+0

这是太少的细节。解决方案取决于你初始化容器的方式,解决'SampleClass',使用它等等。如果你处理异步,同步或多线程,很难给出一个通用的建议。 – 2012-01-30 17:20:57

回答

1

你正在做的绝对是正确的事情。为什么?当应用程序配置不正确时,您正在阻止系统启动。你想要发生的最后一件事是系统实际启动并在以后失败。快速失败!但是,请确保此异常不会丢失。您可以确保记录异常。

虽然有一点需要注意。一般的建议是在类型的构造函数中尽可能少地执行。只需将实例变量中传入的依赖项存储就可以了。这种构建方式非常快速,永远不会真正失败。一般来说,构建依赖关系图应该很快,不应该失败。在你的情况下,这不会是一个问题,因为你希望系统尽快失败(在启动过程中)。尽管如此,为了遵守一般建议,您可能希望在该类型之外提取此验证过程。因此,不要在该构造函数中调用GetConfigurationSettings,而是从组合根(编写容器的代码)直接调用它,并将有效的配置设置对象提供给ConfigurationManager的构造函数。通过这种方式,您不仅可以简化ConfigurationManager,还可以让系统更快地失败。

+0

感谢您的回应。我不确定你的意思是什么“为ConfigurationManager的构造函数提供有效的配置设置对象”ConfigurationManger只是一个保存和验证配置设置的对象。您是否意味着在设置DI容器之前创建一个配置管理器的实例。验证参数,如果它们有效,则将该实例提供给DI容器。查看更新的主要答案 – ministrymason 2012-01-31 09:50:11

-1

我不会把在组成时抛出异常一个很好的做法。这是因为组合可能具有相当复杂和间接的执行逻辑,使合理的异常处理几乎不可能。我怀疑你会发明什么优于可怕

try 
{ 
    var someComponent = context.Resolve<SampleClass>(); 
} 
catch 
{ 
    // Yeah, just stub all exceptions cause you have no idea of what to expect 
} 

我建议的方式,除非他们真的需要做的(它们的构造函数不抛出异常,重新设计类例如,如果它们与绝对没用一个空值构造函数参数)。然后,您需要一些方法来初始化您的应用程序,处理错误并可能与用户交互来完成此操作。

0

核心问题是,您在构图过程中通过执行一些执行来混合对象图的组合和执行。在DI风格中,构造函数应尽可能简单。当你的班级被要求执行一些有意义的工作时,例如当调用GetConfigurationSettings方法时,这是你认真开始的信号。

以这种方式构造事物的主要好处是它使一切都变得更加可预测。构图期间出现错误构图错误,并且执行期间错误确实执行错误。

工作时间也更可预测。我意识到应用程序配置在运行时并不真正改变,但假设你有一个读取文件的类。如果您在构图过程中在构造函数中读取它,则在执行期间您使用该数据时,文件的内容可能会发生变化。但是,如果您在执行过程中阅读文件,则可以避免这种形式的缓存不可避免地出现的时间问题。

如果缓存是算法的一部分,就像我想象的那样是GetConfigurationSettings,那么将它作为执行的一部分而不是组合实现仍然有意义。缓存的值可能与ConfigurationManager实例的寿命不同。即使他们这样做了,编码到构造函数中也只剩下一个选项,其中执行时缓存提供了更大的灵活性它解决了您的异常问题。