MEF 能否解析返回接口的 Func 委托?
Can MEF resolve a Func delegate returning an interface?
底部的代码来自 working WPF 示例应用程序,该应用程序使用 Autofac 进行依赖注入。
我想改为转换为最新版本的 MEF。我还安装了 NuGet 包 CommonServiceLocator (V.1.3) 和 Prism.Core、Prism.Mef 和 Prism.Wpf(所有 6.1)。
当我这样做时
var provider = ServiceLocator.Current.GetInstance<FriendDataProvider>();
我从 FriendDataProvider 的构造函数中的 "Func..." 声明中得到一个 ActivationException。
MEF 完全可以做到这一点吗?如果是,需要什么属性声明?
[Export]
public class FriendDataProvider
{
private readonly Func<IDataService> _dataServiceCreator;
[ImportingConstructor]
public FriendDataProvider(Func<IDataService> dataServiceCreator) // <= DI ERROR
{
_dataServiceCreator = dataServiceCreator;
}
public void DoSomething()
{
using (var service = _dataServiceCreator()) // Factory
{ }
}
}
[Export(typeof(IDataService))]
public class DataService : IDataService
{
public ClassA GetSomething()
{
return new ClassA();
}
public void Dispose()
{ }
}
public interface IDataService : IDisposable
{
ClassA GetSomething();
}
public class ClassA
{ }
您很可能正在寻找 MEF ExportFactory class:
https://msdn.microsoft.com/en-us/library/ff382807(v=vs.110).aspx
它是 AutoFac 的 Owned<> 和 Func<> 创意的混合体。请注意 ExportFactory.CreateExport returns ExportLifetimeContext 是一次性的。处理导出生命周期上下文也将处理注入的部分及其所有依赖项。 ExportFactory 行为略有不同,具体取决于所有者部件的实例化模式。如果所有者 class 是单例,则 ExportFactory 将始终为您创建新实例(行为类似于 Autofac 中的 Func< Owned< T>>),但是如果您将它与 CompositionScopes 结合使用,您将获得类似于 Func< T> 在 AutoFac 中。参见示例:http://blogs.microsoft.co.il/bnaya/2013/01/16/mef-20-mini-series-part-6-composition-scoping-and-lifetime-management/
这是您使用 ExportFactories 重写的示例:
[Export]
public class FriendDataProvider
{
private readonly ExportFactory<IDataService> _dataServiceCreator;
[ImportingConstructor]
public FriendDataProvider(ExportFactory<IDataService> dataServiceCreator) // <= DI ERROR
{
_dataServiceCreator = dataServiceCreator;
}
public void DoSomething()
{
using (var service = _dataServiceCreator.CreateExport()) // Factory
{
}
}
}
[Export(typeof(IDataService))]
public class DataService : IDataService
{
public ClassA GetSomething()
{
return new ClassA();
}
public void Dispose()
{ }
}
public interface IDataService : IDisposable
{
ClassA GetSomething();
}
public class ClassA
{ }
底部的代码来自 working WPF 示例应用程序,该应用程序使用 Autofac 进行依赖注入。 我想改为转换为最新版本的 MEF。我还安装了 NuGet 包 CommonServiceLocator (V.1.3) 和 Prism.Core、Prism.Mef 和 Prism.Wpf(所有 6.1)。 当我这样做时
var provider = ServiceLocator.Current.GetInstance<FriendDataProvider>();
我从 FriendDataProvider 的构造函数中的 "Func..." 声明中得到一个 ActivationException。 MEF 完全可以做到这一点吗?如果是,需要什么属性声明?
[Export]
public class FriendDataProvider
{
private readonly Func<IDataService> _dataServiceCreator;
[ImportingConstructor]
public FriendDataProvider(Func<IDataService> dataServiceCreator) // <= DI ERROR
{
_dataServiceCreator = dataServiceCreator;
}
public void DoSomething()
{
using (var service = _dataServiceCreator()) // Factory
{ }
}
}
[Export(typeof(IDataService))]
public class DataService : IDataService
{
public ClassA GetSomething()
{
return new ClassA();
}
public void Dispose()
{ }
}
public interface IDataService : IDisposable
{
ClassA GetSomething();
}
public class ClassA
{ }
您很可能正在寻找 MEF ExportFactory class: https://msdn.microsoft.com/en-us/library/ff382807(v=vs.110).aspx
它是 AutoFac 的 Owned<> 和 Func<> 创意的混合体。请注意 ExportFactory.CreateExport returns ExportLifetimeContext 是一次性的。处理导出生命周期上下文也将处理注入的部分及其所有依赖项。 ExportFactory 行为略有不同,具体取决于所有者部件的实例化模式。如果所有者 class 是单例,则 ExportFactory 将始终为您创建新实例(行为类似于 Autofac 中的 Func< Owned< T>>),但是如果您将它与 CompositionScopes 结合使用,您将获得类似于 Func< T> 在 AutoFac 中。参见示例:http://blogs.microsoft.co.il/bnaya/2013/01/16/mef-20-mini-series-part-6-composition-scoping-and-lifetime-management/
这是您使用 ExportFactories 重写的示例:
[Export]
public class FriendDataProvider
{
private readonly ExportFactory<IDataService> _dataServiceCreator;
[ImportingConstructor]
public FriendDataProvider(ExportFactory<IDataService> dataServiceCreator) // <= DI ERROR
{
_dataServiceCreator = dataServiceCreator;
}
public void DoSomething()
{
using (var service = _dataServiceCreator.CreateExport()) // Factory
{
}
}
}
[Export(typeof(IDataService))]
public class DataService : IDataService
{
public ClassA GetSomething()
{
return new ClassA();
}
public void Dispose()
{ }
}
public interface IDataService : IDisposable
{
ClassA GetSomething();
}
public class ClassA
{ }