vendredi 14 juin 2019

Dynamically instantiate objects when they're first invoked in autofac c#

Im trying to figure out how to dynamically instantiate class when it's first used. Something like autofac's Lazy does but without refactoring all my classes.

Is there any possiblity to do something like this:

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

}

It has to be done without changing existing codebase (except services registration/ autofac setup or other areas that could be changed without much effort), and all services look's like that:

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

}

My initial idea was to create Proxy class and then while registering services wrap it with that proxy.

It could look something like this:

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

The main issue with this idea is that above proxy class should be created at runtime via reflection and it has to mimic wrapping class behaviour.

I'd appreciate any advice on how to approach this problem. All i want to lazy create dependencies in autofac container (currently if dependency A is requiring dependency B then B is instantiated, i want change this to instantiate B only if any method from A calls B.method).

Thanks!





Aucun commentaire:

Enregistrer un commentaire