【问题标题】:How to set up StructureMap to resolve dependencies in a Windows Service?如何设置 StructureMap 以解决 Windows 服务中的依赖关系?
【发布时间】:2026-02-05 04:50:02
【问题描述】:

我有一个使用 ASP.NET MVC 1.0 构建的网络。它使用 Structuremap 作为 IOC 容器。 如果我像这样在 Application_Start 上注册 IOC 部分,它会很好地工作:

ObjectFactory.Initialize(service =>
    {
        service.ForRequestedType<IOrderRepository>()
               .TheDefaultIsConcreteType<OrderRepository>()
               .CacheBy(InstanceScope.PerRequest);
    });

我必须在 Windows 服务中使用相同的后端。

该服务中有一些计时器可以同时访问 OrderRepository,因此这里的线程是一个问题。

我的第一个想法是像这样在服务的构造函数中注册它:

public Service1()
{
    ObjectFactory.Initialize(service =>
        {
            service.ForRequestedType<IOrderRepository>()
                   .TheDefaultIsConcreteType<OrderRepository>()
                   .CacheBy(InstanceScope.PerRequest);
        });
}

这是缓存的正确位置和正确参数吗?

阅读documentation of Structuremap,我认为最安全的方法是使用默认设置进行缓存:

PerRequest - 默认操作。将为每个请求创建一个新实例。

我的印象是 PerRequest 的意思是 HttpContext,但那是另一个条目:

HttpContext - 将为每个 HttpContext 创建一个实例。缓存HttpContext.Items 集合中的实例。

【问题讨论】:

  • 我认为您通常会在OnStart 中执行此类操作,不是吗?我想这可能会在一个实例上被多次调用,这是不可取的。

标签: .net windows-services inversion-of-control structuremap


【解决方案1】:

根据这篇文章:http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicebase.aspx

可执行文件调用ServiceBase 派生类的构造函数 第一次在服务上调用 Start 。 OnStart 命令处理 方法在构造函数执行后立即调用。这 构造函数在服务第一次执行后不再执行 已加载,因此有必要将执行的处理分开 由 OnStart 执行的构造函数。任何资源 可以通过 OnStop 释放应该在 OnStart 中创建。创造 构造函数中的资源会阻止它们被正确创建 如果服务在 OnStop 释放后再次启动 资源。

听起来构造函数是第一次设置结构图的方法。

【讨论】:

  • 加载和启动服务之间的区别对我来说是新的!很难相信如果您停止并启动服务,则不会再次调用构造函数:但如果这就是文档所说的,我想就是这样。好点子!
【解决方案2】:

老实说,这更像是“我的两分钱”贡献,实际上试图给出一个明确的答案,因为我已经有一段时间没有开发 Windows 服务了,但它就在这里。

以 ASP .Net MVC 应用程序为例,其中容器的配置将在 Global.asax 类的 Application_Start 方法中进行,然后将配置的容器注入自定义控制器工厂;我相信您可以尝试在可执行文件的 Main 函数中进行配置,而不是在服务的构造函数中配置所有内容,因为它只会运行一次,然后将配置的容器注入服务的构造函数中。

我认为,通过这种方式,您将引导应用程序的所有Composition Root,并且服务中的代码将专注于做它应该做的事情。

就像我说的那样已经有一段时间了,我从来没有用 IoC 容器或 DI 来做这件事。祝你好运!

【讨论】:

    最近更新 更多