Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当对象';在autofac c中首次调用#_C#_Reflection_Dependency Injection_Autofac - Fatal编程技术网

C# 当对象';在autofac c中首次调用#

C# 当对象';在autofac c中首次调用#,c#,reflection,dependency-injection,autofac,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 //

我试图弄清楚如何在类首次使用时动态实例化它。类似于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.
    }

}
    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设置或其他不费吹灰之力就能改变的区域除外),所有服务看起来都是这样的:

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

}
我最初的想法是创建代理类,然后在注册服务时用该代理将其包装起来

它可能看起来像这样:

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.
    }

}
    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).
        }
    }
公共类代理
{
私人目标;
私有布尔实例化=false;
私有void实例化()
{
Console.WriteLine(“创建实例”);
_target=Activator.CreateInstance();
}
public void xxx()-每次调用任何包装类型方法get时都应调用此方法。
{
if(实例化==false)
{
实例化();
实例化=真;
}
///继续调用。(我不知道如何通过反射来实现)。
}
}
这种想法的主要问题是,上述代理类应该在运行时通过反射创建,并且它必须模仿包装类的行为

对于如何解决这个问题,我非常感谢你的建议。 我只想在autofac容器中创建依赖项(当前,如果依赖项A需要依赖项B,那么B将被实例化,我想将此更改为仅当来自A的任何方法调用B.method时才实例化B)


谢谢

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

公共类LazyMyServiceProxy:IMyService
{
私人只读懒;
公共LazyMyServiceProxy(Lazy-Lazy)=>this.Lazy=Lazy;
public void SomeMethod()=>this.lazy.SomeMethod();
}
您可以使用以下Autofac注册来使用此代理

builder.RegisterType();
builder.RegisterType().As();

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

公共类LazyMyServiceProxy:IMyService
{
私人只读懒;
公共LazyMyServiceProxy(Lazy-Lazy)=>this.Lazy=Lazy;
public void SomeMethod()=>this.lazy.SomeMethod();
}
您可以使用以下Autofac注册来使用此代理

builder.RegisterType();
builder.RegisterType().As();


“我希望只有在以前调用过某个方法时才调用它。”我不明白这句话的意思。您的问题不清楚。您能否像往常一样向autofac注册IMyService,并在何处使用它?请使用
Lazy
?我的意思是,我希望只有在以前调用过此类时才调用构造函数。在方法调用之前延迟实例化@Fildor我可以这样做,但这需要重写大量的服务及其用法。为什么需要惰性地实例化对象?是的。我肯定我们只是把词弄混了,但是这个——“我的意思是,我希望构造函数只有在这个类以前被调用过的情况下才会被调用”——几乎和构造函数的工作方式完全相反。构造函数是在类被实例化时调用的,而不是之前,并且在该类实例的生命周期中不会再调用它。“我希望只有在SomeMethod被调用之前才会调用它。”我不理解这句话的意思。您的问题不清楚。您能否像往常一样向autofac注册IMyService,并在何处使用它?请使用
Lazy
?我的意思是,我希望只有在以前调用过此类时才调用构造函数。在方法调用之前延迟实例化@Fildor我可以这样做,但这需要重写大量的服务及其用法。为什么需要惰性地实例化对象?是的。我肯定我们只是把词弄混了,但是这个——“我的意思是,我希望构造函数只有在这个类以前被调用过的情况下才会被调用”——几乎和构造函数的工作方式完全相反。构造函数是在实例化类时调用的,而不是在实例化之前,并且在该类实例的生命周期中不再调用。但我需要为我的应用程序中的每个服务动态创建这种代理。最好在集装箱登记期间。每次服务??这在我的脑海中升起了一个巨大的红旗。你需要这个做什么?你是不是经常违反这条规则?是的,每次服务都好像。。。真的很糟糕。我想不出一种方法,你可以在Autofac的开箱即用,这不是我们故意放在那里的东西。您可能可以使用Castle.DynamicProxy执行一些奇特的魔法,但这完全是定制的。Autofac.Extras.DynamicProxy使用Castle.DynamicProxy。但我看了看,并没有看到我想这样做的任何方式。我毫不怀疑这是可行的,但这项工作将不仅仅是修改实际需要更改的服务(很难想象所有这些服务都需要更改)。然后,如果您完成了所有这些工作,这将是令人困惑和难以信任的。这需要一些认真的单元测试。我并没有违反简单的构造函数规则。每个构造函数都很简单,但我们有几十个服务,加载它们需要一些时间。如果它们都是延迟加载的,那么启动就不需要那么多时间。也许我应该提供更详细的描述为什么我需要这个。我想升级我们的集成测试环境。目前,我们正在测试启动中注册所需的服务。我已经在测试基类中注册了所有服务,但现在运行集成测试需要3倍的时间(从1.5分钟到5分钟)。这只能在测试中完成@史蒂文真的。但我需要为我的应用程序中的每个服务动态创建这种代理。最好是在注册期间