我开始使用Windsor,发现了非常非常酷的功能:打字工厂。我了解到每当我使用工厂获取实例时,我也不得不要求它在我不需要时销毁实例。我想知道这是如何适用于一个非常常见的操作,如在磁盘上打开文件。模特:
interface IDisk
IFile OpenFile(string path)
interface IFileFactory
IFile Create(string path)
void Destroy(IFile openFile)
interface IFile // empty, it's not important what it does
class Disk : IDisk
ctor(IFileFactory fileFactory)
IFile OpenFile(string path)
return fileFactory.Create(path)
用户代码:
disk = container.Resolve<IDisk>() // disk is root so this is not SL
file = disk.OpenFile("foo.bar");
// do something with file
现在是摆脱文件的时候了。普通的.NET用户会调用file.Dispose()
。但这次事情有所不同:
IDisposable
的接口(如果它确实那么它将是一个漏洞的抽象);但是File
类实现了IDisposable
所以这是另一种方式:代替Dispose
,IFile
接口有一个额外的方法Close
,它应该从工厂释放文件实例,而工厂又调用{{} 1 {}在Dispose
实例上。要使其工作,File
类必须要知道文件工厂(我不喜欢)或其File
方法:
Destroy
我也不喜欢这个...如果我更改模型以使文件不会自行关闭,但磁盘会关闭文件,我可以避免所有这些麻烦:
class File : IFile
ctor(Action<IFile> destroyCallback)
对于撰写//file.Close() // not supported, by design
disk.Close(file)
和Disk
课程的人来说,这更容易,但我担心我的用户不会欣赏这种“新模式”。
思想?
答案 0 :(得分:2)
好的,让我按顺序解决这个问题:
普通的.NET用户会调用file.Dispose()。
无论您是否使用容器,调用file.Dispose()
都是错误的。 .NET中的规则是你不应该破坏你没有创建的东西。
这适用于.Dispose()
以及ctor(Action<IFile> destroyCallback)
那么谁拥有文件?就你的代码而言,工厂确实如此。因此,工厂有责任在文件后进行清理。
如果您将工厂保留为Disk
的实施细节(您最有可能),那么Disk
是您的表面区域API,用于打开并关闭 文件因此它需要一个Close(IFile file)
方法,当实现细节将其传递给工厂时。
因此该文件的用法如下所示:
var myfile = disk.OpenFile(@"c:\myfile.txt);
try
{
DoSomethingWithTheFile(myFile);
}
finally
{
disk.Close(myFile);
}
[编辑:基于评论]
好吧,如果你期望,并希望你的用户有一些IDisposable
对象,然后给他们一个(我宁愿反对这个,但这不是我的电话)
OpenFile
方法将返回如下所示的对象:
public class FileScope:IDisposable
{
private Action<IFile> close;
public FileScope(IFile file, Action<IFile> close)
{
File = file;
this.close = close;
}
public IFile File {get; private set;}
public void Dispose()
{
close(file);
}
}
关闭代表将回调disk.Close
,如
public FileScope OpenFile(string path)
{
return new FileScope(fileFactory.Create(path),Close);
}