在autofac c#中首次调用对象时动态实例化对象

时间:2019-06-14 12:59:16

标签: c# reflection dependency-injection autofac

我试图弄清楚在首次使用类时如何动态实例化它。就像autofac的Lazy一样,但是没有重构我所有的类。

是否可以做这样的事情:

public class MyService : IMyService {
    public MyService() {
        // I want it to be invoked only if SomeMethod was invoked before.
        // 1. Attempt to invoke SomeMethod
        // 2. call MyService.constructor
        // 3. invoke MyService.SomeMethod()
    }
    public void SomeMethod() {
        ///literally any code.
    }

}

必须在不更改现有代码库的情况下完成此操作(服务注册/ autofac设置或其他无需费力即可更改的区域),并且所有服务如下所示:

public class Service : IService {
    public Service(AnotherService service){
        ///...
    }

}

我最初的想法是创建Proxy类,然后在注册服务时用该代理包装它。

它可能看起来像这样:

    public class Proxy<T>
    {
        private T _target;
        private bool instantiated = false;

        private void Instantiate()
        {
            Console.WriteLine("Creating instance");
            _target = Activator.CreateInstance<T>();
        }
        public void xxx() - this method should be called every time any wrapped type method get's called.
        {
            if (instantiated == false)
            {
                Instantiate();
                instantiated = true;
            }

            /// proceed with invocation. (im not sure how to do this via reflection).
        }
    }

这个想法的主要问题是,上面的代理类应该在运行时通过反射来创建,并且它必须模仿包装类的行为。

对于如何解决此问题的任何建议,我将不胜感激。 我只想懒惰地在autofac容器中创建依赖项(当前,如果依赖项A需要依赖项B,那么实例化B,我想将其更改为仅当A中的任何方法调用B.method时才实例化B)。

谢谢!

1 个答案:

答案 0 :(得分:2)

您要寻找的是代理模式。您可以按如下方式创建惰性代理:

public class LazyMyServiceProxy : IMyService
{
    private readonly Lazy<MyService> lazy;
    public LazyMyServiceProxy(Lazy<MyService> lazy) => this.lazy = lazy;

    public void SomeMethod() => this.lazy.SomeMethod();
}

您可以通过以下Autofac注册来使用此代理。

builder.RegisterType<MyService>();
builder.RegisterType<LazyMyServiceProxy>().As<IMyService>();