基本上,我如何指定可供选择的实现?
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,但这是正确的方法吗?
答案 0 :(得分:7)
如果某个合同中有多个导出,那么您必须全部导入它们(通过声明其上带有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; }
答案 1 :(得分:3)
我认为您不能在MEF中指定您希望单独导入仅限于Foo200实现。
您可以将您的import属性声明为IEnumerable,然后您可以枚举选择以选择您要在自己的代码中使用哪一个,或者您可以确保IFooSvc的两个实现位于不同的程序集中并且在定义MEF目录时只包含其中一个程序集。
答案 2 :(得分:1)
我不熟悉MEF所以这可能稍微偏离基础,但是使用Prism和Unity作为DI容器,您可以通过RegisterType
方法指定关联。当您有多个具体类型实现单个接口时,您可以将名称与它们相关联以进行区分。
IUnityContainer.RegisterType<IFooService, Foo100>("Foo100");
IUnityContainer.RegisterType<IFooService, Foo200>("Foo200");
然后,当你想解决给定的实例时,你可以做...
IUnityContainer.Resolve<IFooService>("Foo200");