我们可以使用MEF或Autofac?
将依赖项作为方法参数而不是构造函数参数注入由于
答案 0 :(得分:3)
我不了解MEF,因为我从未使用它。您可以do it with Unity和with Autofac
来自MSFT文档。
Unity实例化在目标对象范围内携带InjectionMethod属性的方法的参数中定义的依赖对象。然后在将对象返回给调用者之前调用目标对象的属性方法。必须在目标类中应用InjectionMethod属性才能启动方法调用注入。
public class MyObject
{
public SomeOtherObject dependentObject;
[InjectionMethod]
public void Initialize(SomeOtherObject dep)
{
// assign the dependent object to a class-level variable
dependentObject = dep;
}
}
这会将类标记为具有依赖项方法,该类必须在类实例化时调用,并注入其方法参数。
IUnityContainer uContainer = new UnityContainer();
MyObject myInstance = uContainer.Resolve<MyObject>();
// access the dependent object
myInstance.dependentObject.SomeProperty = "Some value";
Autofac在激活服务期间通过lambdas或回调执行此操作。来自Autofac文档
虽然构造函数参数注入是将值传递给正在构造的组件的首选方法,但您也可以使用属性或方法注入来提供值。
属性注入使用可写属性而不是构造函数参数来执行注入。方法注入通过调用方法来设置依赖关系。
// Register the type that you want to resolve with a resolution callback. Within the callback, invoke the method with a resolved dependency.
builder.Register(c => {
var result = new MyObjectType();
var dep = c.Resolve<TheDependency>();
result.SetTheDependency(dep);
return result;
});
另一种选择是注册回调。
builder
.Register<MyObjectType>()
.OnActivating(e => {
var dep = e.Context.Resolve<TheDependency>();
e.Instance.SetTheDependency(dep);
});
两个框架只能在解析时进行方法注入。但是,在实例化对象后,您无法在方法中注入依赖项。在这些情况下,您应该使用工厂来获取您拥有的依赖关系,让工厂通过DI容器解析它。
// Create the factory. The factory will have a static method that the DI system can register a lambda with, so that the factory can resolve through the DI container without being tightly coupled to it.
public class BarFactory
{
private static Func<IBarDependency> internalFactory;
public static void SetFactory(Func<IBarDependency> factory)
{
this.internalFactory = factory;
}
public IBarDependency CreateBar()
{
// Use the DI container lambda assigned in SetFactory to resolve the dependency.
return internalFactory();
}
}
public class DependencyInjectionBootstrap
{
IContainer container;
public void SetupDI()
{
var builder = new ContainerBuilder();
builder.RegisterType<BarDependency>().As<IBarDependency>();
container = builder.Build();
// Tell the factory to resolve all IBarDependencies through our IContainer.
BarFactory.SetFactory(() => container.Resolve<IBarDependency>());
}
}
public class FooViewModel
{
public void ExecuteSave()
{
var barFactory = new BarFactory();
IBarDependency bar = barFactory.CreateBar();
}
}