使用Unity IoC容器解析C#中的包装器类 - c#

我想使用Unity resolve IService到两个不同的实现,以利用包装类,等效于:

 IService service = new DispatcherService(new RealService(), Application.Current.Dispatcher);

DispatcherServiceRealService都实现IService接口的地方。
我有一个包含一些带有异步操作的服务的库。此服务的简化形式如下:

public interface IService
{
    IAsyncResult StartSomeOperation();
    event EventHandler<EventArgs> SomeOperationCompleted;
}

我有所有这些服务的实现。我希望该库保持对WPF和IoC容器的依赖性,但准备好在使用IoC容器和WPF的情况下最佳使用。
我有一个使用Unity IoC容器的WPF Ui。最常见的重复代码是围绕已完成的处理程序-需要使用分派器将它们编组回UI线程。所以我在考虑一个包装器,像这样:

using System;
using System.Windows.Threading;

public class DispatcherService : IService
{
    private Dispatcher dispatcher;
    private IService wrappedService;

    public DispatcherService(IService wrappedService, Dispatcher dispatcher)
    {
        this.wrappedService = wrappedService;
        this.wrappedService.SomeOperationCompleted += this.OnWrappedOperationCompleted;
        this.dispatcher = dispatcher;
    }

    public IAsyncResult StartSomeOperation()
    {
        return this.wrappedService.StartSomeOperation();
    }

    public event EventHandler<EventArgs> SomeOperationCompleted;

    private void OnWrappedOperationCompleted(object sender, EventArgs e)
    {
        if (this.SomeOperationCompleted != null)
        {
            Action completedSynch = () => this.SomeOperationCompleted(sender, e);
            this.dispatcher.Invoke(completedSynch);
        }
    }
}

我可以用类似的代码来更新

IService service = new DispatcherService(new RealService(), Application.Current.Dispatcher);

但是团结并不喜欢我正在组成IService接口的两个不同实现的事实。
此代码严重失败:

    UnityContainer container = new UnityContainer();
    container.RegisterInstance<Dispatcher>(Application.Current.Dispatcher);
    container.RegisterType<IService, RealService>();
    container.RegisterType<IService, DispatcherService>();

    IService created = container.Resolve<IService>();

如果我以其他顺序注册服务,则第一次注册将被覆盖,而我得到的是RealService
Unity可以解决这个问题吗?还是用Unity的AOP完成了?如果是这样,那么在Silverlight中是否可行?是否可以完全不使用原始库中的Unity来完成。
我可以解决“标记”接口子类,即

public interface IServiceWithDispatcher : IService
{
    
}

...

UnityContainer container = new UnityContainer();
container.RegisterInstance<Dispatcher>(Application.Current.Dispatcher);

container.RegisterType<IService, RealService>();
container.RegisterType<IServiceWithDispatcher, DispatcherService>();

但是我认为这不是一个好主意,空接口很丑陋,扩展性也不太好。
解决该对象树的方法是什么?

更新:
与Dzmitry Huba给出的答案一致,这是一些示例代码:
添加对Microsoft.Practices.Unity.StaticFactory的引用
简单的工作代码:

    UnityContainer container = new UnityContainer();

    container.AddNewExtension<StaticFactoryExtension>()
        .Configure<IStaticFactoryConfiguration>()
        .RegisterFactory<IService>(cont =>
                new DispatcherService(new RealService(), Application.Current.Dispatcher));
        
    IService created = container.Resolve<IService>();

更完整的工作代码,可以更好地处理实际服务的潜在依赖关系,例如IoC容器应:

    UnityContainer container = new UnityContainer();
    container.RegisterInstance<Dispatcher>(Application.Current.Dispatcher);
    container.RegisterType<IService, RealService>("Real");
    
    container.AddNewExtension<StaticFactoryExtension>()
        .Configure<IStaticFactoryConfiguration>()
        .RegisterFactory<IService>(cont =>
               new DispatcherService(
                       cont.Resolve<IService>("Real"),
                       cont.Resolve<Dispatcher>()));

    IService created = container.Resolve<IService>()

另外,考虑到工厂注册确实很冗长,并且我将做很多工作,所以我做了一个扩展方法:

public static class ContainerExtensions
{
    public static void RegisterFactory<T>(this IUnityContainer container, FactoryDelegate factoryDelegate)
    {
        container.AddNewExtension<StaticFactoryExtension>()
            .Configure<IStaticFactoryConfiguration>()
            .RegisterFactory<T>(factoryDelegate);
    }
}

c#大神给出的解决方案

您可以使用RegisterType重载,该重载接受基于字符串的名称。在这种情况下,您将执行以下操作:

container.RegisterType<IService, RealService>("real");
container.RegisterType<IService, DispatcherService>("dispatcher");

并用名称宣布您的依赖关系。

[Dependency("real")]

这样可以避免在大多数情况下不是一个好主意的标记界面。

但是,如果要保持代码不受Unity的影响(例如DependencyAttribute),并且在大多数情况下,在应用程序生命周期中仅使用一种实现(例如,仅使用DispatcherService),则基本上可以决定是否需要包装请求的IService是否使用DispatcherService。在这种情况下,您可以查看Static Factory Extension for Unity。工厂委托将了解配置,并基于配置将IService与DispatcherService包装在一起,或者仅返回从容器获取的IService实现。

Python numpy数据指针地址无需更改即可更改 - python

编辑经过一些摆弄之后,到目前为止,我已经隔离了以下状态:一维数组在直接输入变量时提供两个不同的地址,而在使用print()时仅提供一个地址2D数组(或矩阵)在直接输入变量时提供三个不同的地址,在使用print()时提供两个地址3D数组在直接输入变量时提供两个不同的地址,而在使用print()时仅给出一个(显然与一维数组相同)像这样:>>> …

实例化类型<?>的泛型类 - java

我正在为SCJP / OCPJP学习,并且遇到了一个对我来说很奇怪的示例问题。该示例代码实例化了两个通用集合:List<?> list = new ArrayList<?>(); List<? extends Object> list2 = new ArrayList<? extends Object>(); …

无法在Maven surefire中运行多个执行? - java

我想运行名称以ResourceTest.java结尾的测试类,因此我在执行后定义了它们。<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <co…

如何告诉Checker遗留方法将接受Nullable类型? - java

考虑一下:@Nullable Object obj = null; Optional<Object> optional = Optional.ofNullable(obj); 这会失败,因为检查器框架假定ofNullable无法接受null值(毕竟,其参数未标记为@Nullable)。有没有办法告诉Checker-framework这个方法(或我…

Map <String,String>,如何同时打印“键字符串”和“值字符串” [重复] - java

This question already has answers here: How do I efficiently iterate over each entry in a Java Map? (43个答案) 4年前关闭。 我是Java的新手,正在尝试学习Maps的概念。我想出了下面的代码。但是,我想同时打印出“键字符串”和“值字符串”。Process…