Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 注入/解析几乎是单体的对象_C#_Dependency Injection_Inversion Of Control_Castle Windsor_Ioc Container - Fatal编程技术网

C# 注入/解析几乎是单体的对象

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实例通过解析,例如: 问题 我最初认为把它当作单身汉是不好的,因为: 就应用寿命而言,它是瞬态的 它有自

背景

我在WPF应用程序中使用Castle Windsor作为IOC容器。在此应用程序中,用户可以打开单个项目文件,该文件使用
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;
          }
     }