Создание фиктивного контейнера, чтобы внутренний объект можно было переназначить и не потерять (С #) - PullRequest
2 голосов
/ 14 сентября 2011

У меня есть объект, который широко используется в одном из моих классов.Тем не менее, у меня есть другой класс, который хранит ссылку на этот объект, и позже может потребоваться переназначить его.

Как мы все знаем, если класс содержит ссылку на объект, сохраненный в виде переменной-члена, а затемпереназначает его, затем ссылка теряется, и теперь есть два объекта.

Можно утверждать использование ключевого слова ref, но, к сожалению, я не могу, поскольку я сохраняю переменную-член в конструкторе объектов, а затем- присвойте его одному из методов класса.

Решением этой проблемы было бы просто создать небольшой фиктивный контейнерный класс и вместо этого передать его, а затем разделить этот фиктивный контейнер между двумя классами.Тогда оба класса могут свободно переопределить внутреннюю переменную-член, и она никогда не будет потеряна или скопирована.

Теперь вы можете задаться вопросом: «Похоже, у вас уже есть ответ! Какой у вас вопрос?"Ну, у меня нет точного вопроса.Мне просто интересно, если это будет сделано.Это анти-паттерн?Есть ли способ лучше?Рефакторинг?

Спасибо за чтение.

1 Ответ

1 голос
/ 14 сентября 2011

Посмотрите на архитектуру ComponentModel. Там у вас есть интерфейс IServiceProvider , который имеет метод GetService для получения экземпляра зарегистрированной службы. Существует также интерфейс IServiceContainer , который имеет дополнительные методы для отмены регистрации существующих служб и регистрации новых служб, которые затем можно использовать во внешней области. В платформе уже есть реализация, класс ServiceContainer , который можно использовать.

class A
{
    private readonly IServiceContainer _services;
    public A(IServiceContainer services)
    {
        _services = services;
    }

    public void Call() 
    {
         var service = (ISomeService)_services.GetService(typeof(ISomeService));
         service.DoSomething();
    }

    public void ChangeService()
    {
         // set the new service instance as 
         // the ISomeService in the service container
         var newService = new SomeService();
         _services.RemoveService(typeof(ISomeService), true);
         _services.AddService(typeof(ISomeService), newService);             
    }
}

Тогда вы можете сделать:

var svc = new ServiceContainer();
var a1 = new A(svc);
var a2 = new A(svc);
a1.ChangeService();
a1.Call(); // call the created service
a2.Call(); // the service created in a1 will be called
a2.ChangeService();
a1.Call(); // the service created in a2 will be called
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...