C# 注入/解析几乎是单体的对象
背景 我在WPF应用程序中使用Castle Windsor作为IOC容器。在此应用程序中,用户可以打开单个项目文件,该文件使用C# 注入/解析几乎是单体的对象,c#,dependency-injection,inversion-of-control,castle-windsor,ioc-container,C#,Dependency Injection,Inversion Of Control,Castle Windsor,Ioc Container,背景 我在WPF应用程序中使用Castle Windsor作为IOC容器。在此应用程序中,用户可以打开单个项目文件,该文件使用IProjectModel界面的具体版本进行建模。因此,在任何给定时间都有零个或一个可用的IProjectModel实例。我目前正在将其实现者的生活方式定义为暂时的,并且该实现者希望在其构造函数中有一个文件名作为用户(从对话框中)选择的字符串。IProjectModel实例通过解析,例如: 问题 我最初认为把它当作单身汉是不好的,因为: 就应用寿命而言,它是瞬态的 它有自
IProjectModel
界面的具体版本进行建模。因此,在任何给定时间都有零个或一个可用的IProjectModel
实例。我目前正在将其实现者的生活方式定义为暂时的,并且该实现者希望在其构造函数中有一个文件名作为用户(从对话框中)选择的字符串。IProjectModel
实例通过解析,例如:
问题
我最初认为把它当作单身汉是不好的,因为:
就应用寿命而言,它是瞬态的李>
它有自己的依赖项,即要打开的文件名(string
),我认为我无法指定它是否具有单例/作用域的生活方式李>
传递它可以同时打开多个项目
然而,现在我正在创建一个又一个工厂,以便传递当前的IProjectModel
实例,我有点后悔这个决定。让容器将我的对象交给当前的项目模型要容易得多,而不是从对象链的上往下传递
使用温莎城堡应该如何处理这样的情况
它似乎是为此而构建的(范围是当前打开的项目/文件名),但我不知道如何将有关打开的文件的信息输入到中,因为我无法将任何内容注入其中。IProjectModel听起来像是包含数据——也就是说,它不是纯服务
考虑对它进行建模,就像对由数据库支持的服务进行建模一样,但不要连接到数据库,而是使用一些内存结构。它可能与服务实现中的静态成员变量一样简单。比如:
public class ProjectDataService : IProjectDataService
{
private static IProjectModel _projectModel;
public IProjectModel Create(string fileName)
{
if (_projectModel == null)
{
//create it
}
return _projectModel;
}
}
(请注意,您可能需要对成员变量进行一些锁定。)
现在,如果需要切换到同时打开多个项目,请将成员变量更改为列表结构(IList、Dictionary等)
根据您的评论进行编辑
我指的是一旦它被创建了。IOC背后的大想法似乎是“让容器处理依赖关系”,而温莎似乎可以支持这一点,我只是不知道该怎么做。我希望在瞬态对象的构造函数中指定IProjectModel,并让容器解析当前的IProjectModel(如果有)。你的答案是一个懒惰的单身汉,这不是我想要的
我要说的是IProjectModel不是一个真正的服务——它是状态/数据。所以直接注射它没有意义(至少对我来说没有意义)。将其包装在IProjectModel数据服务或IProjectModel“状态管理器”中更符合注入服务,这是DI框架通常所做的
你能注册一个IProjectModel吗?对然而,容器注册通常在应用程序引导时完成,而不是基于用户输入。另外,根据您的描述,您可能需要支持IProjectModel的多个实例。当您请求时,容器如何知道给您哪个实例
作为一个更明显的例子:您是否考虑在构造函数中注入字符串或int?< /p>
让容器处理依赖关系并不是我描述IOC背后的“大想法”的确切方式。它是关于与(或处理)服务依赖性的分离。因此,如果你想注入有状态的东西,我建议你将该状态封装在一个可以像服务一样注入的类中。也许我的问题会更清楚,但我如何才能轻松访问该IProjectModel
?注入IProjectDataService并对其调用Create()。我指的是一旦它已经被创建。IOC背后的大想法似乎是“让容器处理依赖关系”,而温莎似乎可以支持这一点,我只是不知道该怎么做。我想在瞬态对象的构造函数中指定IProjectModel
,并让容器解析当前的IProjectModel
,如果有的话。你的答案是一个懒惰的单身汉,这不是我想要的。是的。注入允许您从文件中获取IProjectModel的服务是一种方法。感谢您的进一步解释IProjectModel
没有状态,它拥有到磁盘上文件的连接(作为存储库)。我希望一些对我来说不明显的温莎特效可以简化实例的传递,但它假设它不存在。
public class ProjectDataService : IProjectDataService
{
private static IProjectModel _projectModel;
public IProjectModel Create(string fileName)
{
if (_projectModel == null)
{
//create it
}
return _projectModel;
}
}