IoC 和工厂模式
IoC and the Factory Pattern
如果我正确理解工厂模式,我可能会有一个工厂来创建我的 Repos,它实现了这样的接口...
public interface IRepoFactory
{
T Get<T>() where T : IRepo
}
并且在该工厂中,对 RepoFactory.Get<IRepo1>()
的调用将 return 一个新生成的 class 实现 IRepo1 的实例。
因此,在 RepoFactory
的定义中,我将创建一个适当类型的新实例...
switch(...)
{
case typeof(IRepo1):
return new Repo1();
}
或者,我假设,我可以为 Repofactory
定义一个构造函数,它将一个表示所有可能的 return 类型的接口作为参数...
public RepoFactory(IRepo1 repo1, IRepo2 repo2, ..., IRepoN repoN) : IRepoFactory
并让我的 IoC 容器完成创建 classes 的工作。
所以,关于我的问题。如果我 do 如上所述创建一个构造函数,这是否意味着每次我包含 IRepoFactory
作为构造函数参数时,我都会得到一个新的 Repo1、Repo2 实例。 ..,报告?那是一个资源繁重的过程吗?如果在任何给定情况下,我可能只需要可用存储库总数的一部分,这是一种浪费的做事方式吗?
有没有办法让 IoC(在我的例子中是 Unity)只在需要的时候创建一个实例,如果你愿意的话,那就是延迟加载?还是我什么都不担心?
如果你有一个容器,那么你可以让容器在需要的时候解析 repo 的类型。
这是一个粗略的示例,说明您如何做到这一点。请注意,您将更改代码以适合您的特定容器,并且这里的假设是您也已经将容器配置为知道热点以解析您想要的类型。
public class DefaultRepoFactory : IRepoFactory {
IUnityContainer container;
public DefaultRepoFactory(IUnityContainer container) {
this.container = container;
}
public T Get<T>() where T : IRepo {
return (T)container.Resolve<T>();
}
}
配置
IUnityContainer myContainer = new UnityContainer();
IRepoFactory myDefaultFactory = new DefaultRepoFactory(myContainer);
myContainer.RegisterInstance<IRepoFactory>(myDefaultFactory);
你误会了Factory
。工厂应该创建实例。这意味着除了 Di 容器或 LifeTimeScope 之外,工厂构造函数中不应包含任何内容。
您可以使用自己的工厂,也可以使用自动生成的工厂。
我不熟悉 Unity,但我查过他们有。
public class MyService : IMyService
{
private readonly Func<IRepo1> _repo1;
public MyService(Func<IRepo1> repo1)
{
_repo1 = repo1;
}
public void Method1()
{
var myRepo = _repo1();
}
public void Method2()
{
//Repo1 instance will be different than in Method1
var myRepo = _repo1();
}
}
如果我正确理解工厂模式,我可能会有一个工厂来创建我的 Repos,它实现了这样的接口...
public interface IRepoFactory
{
T Get<T>() where T : IRepo
}
并且在该工厂中,对 RepoFactory.Get<IRepo1>()
的调用将 return 一个新生成的 class 实现 IRepo1 的实例。
因此,在 RepoFactory
的定义中,我将创建一个适当类型的新实例...
switch(...)
{
case typeof(IRepo1):
return new Repo1();
}
或者,我假设,我可以为 Repofactory
定义一个构造函数,它将一个表示所有可能的 return 类型的接口作为参数...
public RepoFactory(IRepo1 repo1, IRepo2 repo2, ..., IRepoN repoN) : IRepoFactory
并让我的 IoC 容器完成创建 classes 的工作。
所以,关于我的问题。如果我 do 如上所述创建一个构造函数,这是否意味着每次我包含 IRepoFactory
作为构造函数参数时,我都会得到一个新的 Repo1、Repo2 实例。 ..,报告?那是一个资源繁重的过程吗?如果在任何给定情况下,我可能只需要可用存储库总数的一部分,这是一种浪费的做事方式吗?
有没有办法让 IoC(在我的例子中是 Unity)只在需要的时候创建一个实例,如果你愿意的话,那就是延迟加载?还是我什么都不担心?
如果你有一个容器,那么你可以让容器在需要的时候解析 repo 的类型。
这是一个粗略的示例,说明您如何做到这一点。请注意,您将更改代码以适合您的特定容器,并且这里的假设是您也已经将容器配置为知道热点以解析您想要的类型。
public class DefaultRepoFactory : IRepoFactory {
IUnityContainer container;
public DefaultRepoFactory(IUnityContainer container) {
this.container = container;
}
public T Get<T>() where T : IRepo {
return (T)container.Resolve<T>();
}
}
配置
IUnityContainer myContainer = new UnityContainer();
IRepoFactory myDefaultFactory = new DefaultRepoFactory(myContainer);
myContainer.RegisterInstance<IRepoFactory>(myDefaultFactory);
你误会了Factory
。工厂应该创建实例。这意味着除了 Di 容器或 LifeTimeScope 之外,工厂构造函数中不应包含任何内容。
您可以使用自己的工厂,也可以使用自动生成的工厂。
我不熟悉 Unity,但我查过他们有。
public class MyService : IMyService
{
private readonly Func<IRepo1> _repo1;
public MyService(Func<IRepo1> repo1)
{
_repo1 = repo1;
}
public void Method1()
{
var myRepo = _repo1();
}
public void Method2()
{
//Repo1 instance will be different than in Method1
var myRepo = _repo1();
}
}