我试图弄清楚在首次使用类时如何动态实例化它。就像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)。
谢谢!
答案 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>();