IoC和工厂模式

时间:2016-04-01 12:32:40

标签: c# inversion-of-control unity-container factory

如果我正确理解工厂模式,我可能会有一个工厂来创建我的Repos,它实现了这样的界面......

javax.net.ssl.SSLHandshakeException: Handshake failed     
com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:390c)
com.android.okhttp.Connection.upgradeToTls(Connection.java:201)

在该工厂中,对public interface IRepoFactory { T Get<T>() where T : IRepo } 的调用将返回实现IRepo1的类的新创建实例。

因此,在RepoFactory.Get<IRepo1>()的定义中,我将创建一个适当类型的新实例......

RepoFactory

或者,我假设,我可以为switch(...) { case typeof(IRepo1): return new Repo1(); } 定义一个构造函数,它将参数作为参数,代表所有可能的返回类型......

Repofactory

让我的IoC容器完成创建类的工作。

所以,对我的问题。如果我如上所述创建构造函数,那么这并不意味着每次我将public RepoFactory(IRepo1 repo1, IRepo2 repo2, ..., IRepoN repoN) : IRepoFactory 作为构造函数参数包含时,我将获得Repo1,Repo2,...的新实例。 ,RepoN?这是一个资源繁重的过程吗?如果在任何特定情况下,我可能只需要可用回购总数的一部分,这是一种浪费的做法吗?

有没有办法让IoC(在我的情况下为Unity)只在需要时创建一个实例,如果你愿意,可以使用延迟加载?或者我只是担心什么?

2 个答案:

答案 0 :(得分:1)

如果您有容器,那么您可以让容器在需要时解析回购的类型。

这是一个如何做到这一点的粗略示例。请注意,您将更改代码以适合您的特定容器,此处的假设是您还应该已经将容器配置为知道热以解析所需的类型。

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);

答案 1 :(得分:1)

你误解了Factory。工厂应该创建实例。这意味着什么都不应该在Di container或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();
        }
    }