Динамически создавать объекты при их первом вызове в autofac c # - PullRequest
0 голосов
/ 14 июня 2019

Я пытаюсь понять, как динамически создавать экземпляр класса при его первом использовании. Что-то вроде Lazy от autofac, но без рефакторинга всех моих классов.

Есть ли возможность сделать что-то вроде этого:

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 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, я хочу изменить это на создание экземпляра B, только если какой-либо метод из A вызывает B.method).

Спасибо!

1 Ответ

2 голосов
/ 14 июня 2019

То, что вы ищете, это шаблон Proxy.Вы можете создать ленивый прокси-сервер следующим образом:

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>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...