温莎城堡-如何解决名字? [英] Castle Windsor - how to resolve by name?

查看:83
本文介绍了温莎城堡-如何解决名字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序使用 SignalR客户端/服务器通信框架。如果您不熟悉它,则服务器端应用程序通常包含一个或多个集线器类(类似于asmx Web服务),每个类都提供可由客户端调用的方法。在启动过程中,客户端需要首先创建一个连接,然后为其需要与之交谈的每个集线器创建一个代理,例如:-

My application uses the "SignalR" client/server comms framework. If you aren't familiar with it, the server-side app typically contains one or more "hub" classes (similar to asmx web services), each providing methods that can be called by a client. During startup, the client needs to first create a connection, then create a "proxy" for each hub that it will need to talk to, e.g.:-

var hubConnection = new HubConnection("http://...");
var fooHubProxy = hubConnection.CreateHubProxy("FooHub");
var barHubProxy = hubConnection.CreateHubProxy("BarHub");
...etc...

传递给 CreateHubProxy()是服务器端中心类的名称。方法返回类型为 IHubProxy

The string parameter passed to CreateHubProxy() is the name of the server-side hub class. The method return type is IHubProxy.

感觉我应该可以在这里使用Windsor,但是我我努力寻找解决方案。我的第一个想法是实例化集线器代理,并向Windsor(按名称)注册这些实例,例如

It feels like I should be able to utilise Windsor here, but I'm struggling to find a solution. My first thought was to instantiate the hub proxies and register these instances with Windsor (by name), e.g.

var fooHubProxy = hubConnection.CreateHubProxy("FooHub");
container.Register(Component.For<IHubProxy>().Instance(fooHubProxy).LifestyleSingleton().Named("FooHub"));
...etc...

问题是当一个班级需要一个集线器时代理,按名称解析它的唯一方法是使用服务定位器模式,不建议这样做。温莎还有哪些其他功能(例如,打字工厂等)在这里有用?

The problem is that when a class needs a hub proxy, the only way to resolve it by name is to use service locator pattern, which isn't recommended. What other Windsor features (e.g. typed factories, etc.) might be useful here?

编辑

我刚刚找到了Windsor的 .UsingFactoryMethod ,想知道这是否可行,以简化集线器注册:

I've just found Windsor's .UsingFactoryMethod, and am wondering if this would work, to simplify hub registration:

container.Register(Component.For<IHubProxy>()
                   .UsingFactoryMethod((kernel, context) => hubConnection.CreateHubProxy("FooHub"))
                   .LifestyleSingleton()
                   .Named("FooHub"));

我想我仍然有如何按名称解析的问题。

I guess I still have the problem of how to resolve by name though.

推荐答案

好的,我想我找到了一种可能的解决方案,部分使用了此处,其中显示了如何注册 Func<>

Okay, I think I've found a possible solution, partly using the approach detailed here which shows how it is possible to register Func<>s with Windsor.

首先,我注册一个委托(Func<>),该委托使用容器按名称解析:-

First, I register a delegate (Func<>) that uses the container to resolve by name:-

Container.Register(Component.For<Func<string, IHubProxy>>()
                   .Instance(name => Container.Resolve<IHubProxy>(name))
                   .LifestyleSingleton());

将其视为IHubProxy工厂。

Think of this as an IHubProxy "factory".

接下来,我按照原始问题中的详细说明注册集线器代理:-

Next, I register my hub proxies as detailed in my original question:-

container.Register(Component.For<IHubProxy>()
               .UsingFactoryMethod((kernel, context) => hubConnection.CreateHubProxy("FooHub"))
               .LifestyleSingleton()
               .Named("FooHub"));
container.Register(Component.For<IHubProxy>()
               .UsingFactoryMethod((kernel, context) => hubConnection.CreateHubProxy("BarHub"))
               .LifestyleSingleton()
               .Named("BarHub"));

以下是一个需要中心代理实例的类的示例:-

Here is an example of a class that needs instances of the hub proxies:-

public class SomeClass
{
    private IHubProxy _fooHub;
    private IHubProxy _barHub;

    public SomeClass(Func<string, IHubProxy> hubProxyFactory)
    {
        _fooHub = hubProxyFactory("FooHub");
        _barHub = hubProxyFactory("BarHub");
    }
}

到目前为止尚未尝试,但看起来很有希望。这是一个聪明的解决方案,但是注入Func<>感觉有点棘手,所以我仍然很想听到其他解决我的问题的方法。

Untried so far, but it looks promising. It's a clever solution but injecting the Func<> feels a little hacky, so I would still be keen to hear of other possible solutions to my problem.

这篇关于温莎城堡-如何解决名字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆