繁体   English   中英

PRISM + MEF - 如何指定要使用的导出?

[英]PRISM + MEF — How to specify which export to use?

基本上,我如何指定我的哪些实现可供选择?

FooService.cs

public interface IFooService
{
    Int32 GetFoo();
}

[Export(typeof(IFooService))]
public sealed class Foo100 : IFooService
{
    public Int32 GetFoo()
    {
        return 100;
    }
}


[Export(typeof(IFooService))]
public sealed class Foo200 : IFooService
{
    public Int32 GetFoo()
    {
        return 200;
    }
}

ClientViewModel.cs

[Export()]
public class ClientViewModel : NotificationObject
{
    [Import()]
    private IFooService FooSvc { get; set; }

    public Int32 FooNumber
    {
        get { return FooSvc.GetFoo(); }
    }
}

Boostrapper.cs

public sealed class ClientBootstrapper : MefBootstrapper
{
    protected override void ConfigureAggregateCatalog()
    {
        base.ConfigureAggregateCatalog();

        //Add the executing assembly to the catalog.
        AggregateCatalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
    }

    protected override DependencyObject CreateShell()
    {
        return Container.GetExportedValue<ClientShell>();
    }

    protected override void InitializeShell()
    {
        base.InitializeShell();

        Application.Current.MainWindow = (Window)Shell;
        Application.Current.MainWindow.Show();
    }
}

ClientShell.xaml.cs

[Export()]
public partial class ClientShell : Window
{
    [Import()]
    public ClientViewModel ViewModel
    {
        get
        {
            return DataContext as ClientViewModel;
        }
        private set
        {
            DataContext = value;
        }
    }

    public ClientShell()
    {
        InitializeComponent();
    }
}

我不知道从哪里开始设置我的应用程序以注入正确的应用程序(在这种情况下,我希望注入Foo100。我知道我可以让它们自己导出并指定Foo100而不是IFooService ,但这是正确的方法吗?

如果存在多个具有特定合同的导出,则必须将它们全部导入(通过声明具有ImportMany属性的集合类型的属性)或通过指定合同的名称使合同更具体:

[Export("Foo100", typeof(IFooService))]
public sealed class Foo100 : IFooService
{
    public Int32 GetFoo()
    {
        return 100;
    }
}


[Export("Foo200", typeof(IFooService))]
public sealed class Foo200 : IFooService
{
    public Int32 GetFoo()
    {
        return 200;
    }
}

-

[Import("Foo100", typeof(IFooService)]
private IFooService FooSvc { get; set; }

我不认为你可以在MEF中指定你希望你的单例导入仅绑定到Foo200实现。

您可以将您的import属性声明为IEnumerable,然后您可以枚举选择以选择您要在自己的代码中使用哪一个,或者您可以确保IFooSvc的两个实现驻留在不同的程序集中,并且仅当您定义MEF目录时,会包含其中一个程序集。

我不熟悉MEF所以这可能稍微偏离基础,但是使用Prism和Unity作为DI容器,您可以通过RegisterType方法指定关联。 当您有多个具体类型实现单个接口时,您可以将名称与它们相关联以进行区分。

IUnityContainer.RegisterType<IFooService, Foo100>("Foo100");
IUnityContainer.RegisterType<IFooService, Foo200>("Foo200");

然后当你想要解决给定的实例时,你可以做...

IUnityContainer.Resolve<IFooService>("Foo200");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM