工厂方法只调用一次
Factory method only called once
以下是我的注册码
container.RegisterType<IFoo, Foo>(
new InjectionConstructor(typeof (IEnumerable<int>),
new ResolvedParameter<IBar1>,
new InjectionParameter<IBar2>(CreateBar2(container)))
问题是 CreateBar2(container)
只在程序启动时调用一次,我需要在每次 IFoo 解决时调用它
另一个问题,哪个是最佳实践
container.RegisterType<IFoo, Foo>(
new InjectionConstructor(typeof (IEnumerable<int>),
new ResolvedParameter<IBar1>,
new InjectionParameter<IBar2>(CreateBar2(container)))
或
container.RegisterType<IFoo, Foo>(
new InjectionConstructor(typeof (IEnumerable<int>),
new ResolvedParameter<IBar1>,
CreateBar2(container))
首先,你需要使用不同的LifetimeManager. TransientLifetimeManager每次都会解析一个新的实例。
container.RegisterType<IFoo, Foo>(
new InjectionConstructor(typeof (IEnumerable<int>),
new ResolvedParameter<IBar1>,
new InjectionParameter<IBar2>(CreateBar2(container)),
new TransientLifetimeManager())
这意味着每次 IFoo
被注入或解析时,每次都会调用构造函数。但是,您似乎正在注入一种方法,该方法将在注册时执行 - CreateBar2(container)
。这和写是一样的:
var bar2 = CreateBar2(container); // Called once.
container.RegisterType<IFoo, Foo>(
new InjectionConstructor(typeof (IEnumerable<int>),
new ResolvedParameter<IBar1>,
new InjectionParameter<IBar2>(bar2))
我建议您将其抽象为 class 并注入。这样你也可以控制对它的调用。
public interface ICreateBar2
{
IBar CreateBar2();
}
public class CreateBar2
{
private IUnityContainer _container;
public CreateBar(IUnityContainer container)
{
_container = container;
}
public IBar CreateBar2()
{
// Do stuff.
return CreateBar2(_container); // Or what you need to do?
}
}
并将您的注册更改为
container.RegisterType<IFoo, Foo>(
new InjectionConstructor(typeof (IEnumerable<int>),
new ResolvedParameter<IBar1>,
new ResolvedParameter<ICreateBar2>),
new TransientLifetimeManager())
container.RegisterType<ICreateBar2, CreateBar2>(new TransientLifetimeManager());
或者可能 RegisterInstance,如果它更适合您的需要?
请记住更改 IFoo
的构造函数以接受 ICreateBar
。这种方法最好的一点是您不再需要 InjectionConstructor
,因为所有参数都可以通过 Unity
.
来解析
container.RegisterType<IFoo, Foo>(new TransientLifetimeManager());
如果您真的需要在当前范围内保留 CreateBar2()
方法,您可以注入一个 Func
,它实际上 returns 与 CreateBar2()
具有相同的值。
我不知道 CreateBar() 的完整签名,但您可以这样做:
container.RegisterType<IFoo, Foo>(
new InjectionConstructor(typeof (IEnumerable<int>),
new ResolvedParameter<IBar1>,
new InjectionParameter<Func<IBar2>>(
new Func<IBar2>(()=> CreateBar2(container)));
但是现在您需要将 Func<IBar2>
注入到 IFoo
构造函数中。这将导致它在您在构造函数中使用它时执行。
public class Foo : IFoo
{
IBar1 _bar1;
IBar2 _bar2;
public Bar(IBar1 bar1, Func<IBar2> bar2Func)
{
_bar1 = bar1;
_bar2 = bar2Func();
}
}
以下是我的注册码
container.RegisterType<IFoo, Foo>(
new InjectionConstructor(typeof (IEnumerable<int>),
new ResolvedParameter<IBar1>,
new InjectionParameter<IBar2>(CreateBar2(container)))
问题是 CreateBar2(container)
只在程序启动时调用一次,我需要在每次 IFoo 解决时调用它
另一个问题,哪个是最佳实践
container.RegisterType<IFoo, Foo>(
new InjectionConstructor(typeof (IEnumerable<int>),
new ResolvedParameter<IBar1>,
new InjectionParameter<IBar2>(CreateBar2(container)))
或
container.RegisterType<IFoo, Foo>(
new InjectionConstructor(typeof (IEnumerable<int>),
new ResolvedParameter<IBar1>,
CreateBar2(container))
首先,你需要使用不同的LifetimeManager. TransientLifetimeManager每次都会解析一个新的实例。
container.RegisterType<IFoo, Foo>(
new InjectionConstructor(typeof (IEnumerable<int>),
new ResolvedParameter<IBar1>,
new InjectionParameter<IBar2>(CreateBar2(container)),
new TransientLifetimeManager())
这意味着每次 IFoo
被注入或解析时,每次都会调用构造函数。但是,您似乎正在注入一种方法,该方法将在注册时执行 - CreateBar2(container)
。这和写是一样的:
var bar2 = CreateBar2(container); // Called once.
container.RegisterType<IFoo, Foo>(
new InjectionConstructor(typeof (IEnumerable<int>),
new ResolvedParameter<IBar1>,
new InjectionParameter<IBar2>(bar2))
我建议您将其抽象为 class 并注入。这样你也可以控制对它的调用。
public interface ICreateBar2
{
IBar CreateBar2();
}
public class CreateBar2
{
private IUnityContainer _container;
public CreateBar(IUnityContainer container)
{
_container = container;
}
public IBar CreateBar2()
{
// Do stuff.
return CreateBar2(_container); // Or what you need to do?
}
}
并将您的注册更改为
container.RegisterType<IFoo, Foo>(
new InjectionConstructor(typeof (IEnumerable<int>),
new ResolvedParameter<IBar1>,
new ResolvedParameter<ICreateBar2>),
new TransientLifetimeManager())
container.RegisterType<ICreateBar2, CreateBar2>(new TransientLifetimeManager());
或者可能 RegisterInstance,如果它更适合您的需要?
请记住更改 IFoo
的构造函数以接受 ICreateBar
。这种方法最好的一点是您不再需要 InjectionConstructor
,因为所有参数都可以通过 Unity
.
container.RegisterType<IFoo, Foo>(new TransientLifetimeManager());
如果您真的需要在当前范围内保留 CreateBar2()
方法,您可以注入一个 Func
,它实际上 returns 与 CreateBar2()
具有相同的值。
我不知道 CreateBar() 的完整签名,但您可以这样做:
container.RegisterType<IFoo, Foo>(
new InjectionConstructor(typeof (IEnumerable<int>),
new ResolvedParameter<IBar1>,
new InjectionParameter<Func<IBar2>>(
new Func<IBar2>(()=> CreateBar2(container)));
但是现在您需要将 Func<IBar2>
注入到 IFoo
构造函数中。这将导致它在您在构造函数中使用它时执行。
public class Foo : IFoo
{
IBar1 _bar1;
IBar2 _bar2;
public Bar(IBar1 bar1, Func<IBar2> bar2Func)
{
_bar1 = bar1;
_bar2 = bar2Func();
}
}