0

因此,我在 Windows 服务中实现了一个自托管的有状态 Wcf 服务。
我将此服务用作远程硬件驱动程序(有点)。
由于服务必须强制对底层硬件进行串行访问,我将服务设置为具有以下属性的唯一单个实例:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

它可以正常工作,但现在我想让 Castle 为我管理依赖项,麻烦就从这里开始了。
我发现依赖注入和单实例模式不能很好地协同工作(这里是一个参考,但你可以找到更多的谷歌搜索)......

请注意,我不能使用 Castle 提供的标准单例,因为我需要为系统中安装的每个设备使用不同的实例(可以同时有多个)。所以使用 Castle 默认生命周期对我来说不是一个选项。

编辑
根据要求,我添加了用于注册和解析服务的代码,即使我认为它非常标准并且没有什么需要强调的。
这是我用来注册服务的代码:

container.Register(Component.For<IMyService>().ImplementedBy<MyService>().LifeStyle.Transient);

这是我用来解析服务的代码:

public ServiceHostBase Build<T>(SelfHostConfiguration configuration)
{
    // Service configuration is done by code, not by App.config
    Uri[] uris = configuration.Select(e => e.Uri).ToArray();

    var serviceName = typeof(T).AssemblyQualifiedName;
    DefaultServiceHostFactory factory = new DefaultServiceHostFactory();
    var serviceHost = factory.CreateServiceHost(serviceName, uris);
    return serviceHost;
}

没什么特别的,真的,也许它还是有用的。

问题:有没有人能够让 Castle 和 InstanceContextMode.Single 一起工作?甚至可能吗?
你能分享你的解决方案/想法吗?

4

1 回答 1

1

使用 WCF 工具时,您应该删除该ServiceBehavior属性并依靠 Windsor 来管理您的服务实例生命周期。如果将其设置InstanceContextModeSingle它将导致 WCF 使用自己的实例管理并有效地绕过 Windsor。

WCF 中的默认实例上下文模式将根据绑定(通常是 PerSession 或 PerCall)而有所不同,但在大多数情况下,它应该可以在您在 Windsor/WCF Facility 注册时指定的任何生活方式下正常工作。

更新

假设您要公开的每个设备的详细信息仅包含“名称”和“端口”,并且可以在启动时发现这些详细信息,您可以为每个设备注册并公开一个单例服务,如下所示:

var devices = GetDevices();
foreach (var device in devices)
{
    container.Register(
        Component.For<IMyService>()
            .ImplementedBy<MyService>()
            .Named("MyService:" + device.Name)
            .LifestyleSingleton()
            .DependsOn(Dependency.OnValue("devicePort", device.Port))
            .AsWcfService(new DefaultServiceModel()
                .AddEndpoints(
                    WcfEndpoint
                        .BoundTo(binding)
                        .At(new EndpointAddress("net.tcp://localhost/MyService/" + device.Name)))
            ));
}
于 2015-09-25T02:06:41.533 回答