我注册了
container.RegisterType<IService, MyService>();
我想创建一个类似于
的辅助类public class MyHelper
{
private IService _service;
public void SomeMethod
{
_service.RunSomething();
}
}
我真的希望这个_serivce只是神奇地映射到MyService构造函数而不是null,因为我没有在其他任何地方找到IService或Service实例。
如何根据Unity映射使这个_service自我映射?
答案 0 :(得分:2)
您仍然必须将注入的IService
分配给您的实例。这通常通过构造函数完成:
public class MyHelper {
private readonly IService _service;
public MyHelper(IService service) {
_service = service;
}
public void SomeMethod() {
// _service isn't null anymore
}
}
编辑:查看您的评论我不认为您正确使用IoC,因此我会尝试填补一些空白。您不希望创建MyHelper
的新实例,无论创建它必须具有IService
和任何其他依赖项MyHelper
的知识。相反,您可以创建一个工厂来处理创建MyHelper
的新实例,该实例也将处理其依赖项。这样,您可以设置IoC来解决此工厂的依赖关系。
public interface IInstanceFactory<out T> {
T Create();
}
public class MyHelperFactory : IInstanceFactory<MyHelper> {
private readonly Func<MyHelper> _myHelperFactory;
public MyHelperFactory(Func<MyHelper> myHelperFactory) {
_myHelperFactory = myHelperFactory;
}
public MyHelper Create() {
return _myHelperFactory();
}
}
所以我们现在有一个存储Func
的工厂,用于创建MyHelper
的实例。它所做的只是执行我们将在IoC设置中定义的功能。该函数所做的就是返回MyHelper
的新实例。
现在我们可以设置IoC来为我们处理其他所有事情。因此,在您的IoC设置中,您可以执行以下操作(我不了解Unity,因此我将使用Autofac向您展示.Unity应该能够完成我正在展示的所有内容。)
注册服务:
container.RegisterType<MyService>().As<IService>();
注册工厂:(这是魔术发生的地方)
container.Resolve(b => {
var service = b.Resolve<IService>();
var myHelperFactory = new Func<MyHelper>(() => new MyHelper(service));
return new MyHelperFactory(myHelperFactory);
}).As<IInstanceFactory<MyHelper>>();
我们在此处获得了IService
的实例,我们已将其注册为MyService
。然后,我们创建一个Func<MyHelper>
,只创建MyHelper
的新实例并传递我们刚解决的IService
实例。最后,我们返回一个新的MyHelperFactory
并将Func<MyHelper>
传递给工厂。
所以我们假设我们有班级Foo
。并且Foo
需要在不了解MyHelper
依赖项的情况下创建MyHelper's
的实例:
public class Foo {
private readonly IMyHelperFactory _factory;
public Foo(IMyHelperFactory factory) {
_factory = factory;
}
public void MethodThatCreatesMyHelper() {
var instance = _factory.Create();
// you now have a valid instance of `MyHelper`
}
}
您要做的最后一件事就是从容器中解析Foo
(只要您设置它):
var fooInstance = container.Resolve<Foo>();
fooInstance.MethodThatCreatesMyHelper();
这是我上面示例的gist。需要注意的是Foo
可以在不了解其依赖关系的情况下创建实例MyHelper
。
答案 1 :(得分:1)
一种技术是使用构造函数中构建 MyHelper
对象的对象初始化IService
。这可以像lambda exssion一样简单:
public class MyHelper : IMyHelper
{
private Func<IService> _serviceBuilderFunc;
public MyHelper(Func<IService> serviceBuilderFunc)
{
_serviceBuilderFunc = serviceBuilderFunc;
}
public void SomeMethod()
{
var svc = _serviceBuilderFunc();
svc.RunSomething();
}
}
然后在Unity容器配置中使用RegisterType()
的重载来指定构造函数参数:
var serviceBuilderFunc = () => new MyService();
container.RegisterType<IMyHelper, MyHelper>(
new InjectionConstructor(serviceBuilderFunc));