Mik*_*fer 6 .net dependency-injection exception
假设我有这样一个类:
public class Foo
{
public Bar RequiredProperty { get; set;}
public void Baz()
{
if (this.RequiredProperty == null)
{
// Which exception should I throw?
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的解决方案有一个专门设计用于重用的类,而不必Bar一次又一次地将大量参数传递给该方法.那么,当Bar未初始化为非空值时,我应该抛出什么?
更多信息
我实际上是在编写自己的代码解析器和格式化程序.称之为对象课程.其中一个类HtmlCodeFormatter具有以下属性(以表示依赖注入):
public IFormatter Formatter { get; set; }
public IParser Parsre { get; set; }
Run Code Online (Sandbox Code Playgroud)
这允许我编写任意数量的特定于语言的解析器和格式化程序.例如,我有一个CSharpParser和一个JavascriptParser.我也有HtmlCodeFormatter,并且计划另一个(可疑的实用程序).
这个想法是你可以实例化HtmlFormatter使用对象初始化器,如下所示:
var formatter = new HtmlCodeFormatter()
{
Parser = new CSharpParser();
Formatter = new HtmlCodeFormatter();
};
formatter.Format("Console.WriteLine(\"Hello, world!\"));
Run Code Online (Sandbox Code Playgroud)
当HtmlCodeFormatter.Format被调用时,它需要能够验证这两个解析器以及格式已经提供.真的,这没问题,但我有点不知道抛出哪个异常.我倾向于InvalidOperationException,但我不完全确定这是最好的选择.
ale*_*exn 12
我会抛出一个InvalidOperationException.MSDN定义是:
方法调用对于对象的当前状态无效时引发的异常.
但是,我建议使用构造函数注入而不是setter注入.这可确保您拥有有效的解析器和格式化程序.如果在构造函数中传递null,则抛出ArgumentNullException.
通过使用Propery Injection,您隐含地告诉编译器,开发人员以及DI容器,依赖项是可选的.这是因为没有人强迫您分配属性值.
如果确实需要依赖项,则应该重构构造函数注入.这将有效地使所需的依赖:
public class Foo
{
private readonly Bar bar;
public Foo(Bar bar)
{
if (bar == null)
{
throw new ArgumentNullException("bar");
}
this.bar = bar;
}
public Bar RequiredProperty
{
get { return this.bar; }
}
public void Baz()
{
// this.bar is now GUARANTEED to be initialized,
// so no checks are required
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,构造函数Guard Clause(抛出ArgumentNullException)有效地保护了类的不变量,而readonly关键字进一步加强了这种不变量.
使用类'不变量的依赖部分,您不再有任何时间耦合,您现在可以实现所有成员,而不必担心是否已分配依赖项.
| 归档时间: |
|
| 查看次数: |
3800 次 |
| 最近记录: |