.NET IoC: экземпляр типа регистра, созданный во время фактического выполнения программы - PullRequest
0 голосов
/ 03 октября 2011

Я все еще пытаюсь разобраться с IoC, и я полагаю, что на самом деле я нахожусь на совершенно неверном пути в отношении того, как нужно структурировать разрешение потока программ / типов.

У меня есть приложение WinForms, написанное в значительной степени «по-старому», которое я хочу преобразовать в структуру IoC с использованием Autofac для практических целей.
Он состоит из основной формы, из которой можно открыть диалоговое окно входа в систему, и после успешного подключения к серверу можно выполнять различные функции для сервера из пользовательского интерфейса с помощью веб-службы.

Я начал настраивать контейнер Autofac, зарегистрировав классы MainForm и LogonDialog, поэтому мой код в Program.cs выглядит следующим образом:

    [STAThread]
    private static void Main()
    {
        Autofac.IContainer container = buildContainer();

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(container.Resolve<Form>());
    }

    private static Autofac.IContainer buildContainer()
    {
        ContainerBuilder builder = new ContainerBuilder();

        builder.RegisterType<MainForm>().As<Form>().SingleInstance();
        builder.Register(c => new LogonDialog());

        IContainer container = builder.Build();

        return container;
    }

Конструктор MainForm принимает Func<LogonDialog>, который позже используется для создания экземпляра диалогового окна входа в предложение using. Это работает.

Я застрял в следующей точке:

После успешного входа в систему LogonDialog возвращает объект Connection, который содержит различную информацию о подключении к серверу. Одним из его свойств является ссылка на веб-сервис (IBackendWebservice), который затем передается другим объектам, которые реализуют различные функциональные возможности приложения (смутно способом ViewModel / Controller). Так что у меня может быть конструктор типа FindRecordController(IBackendWebservice dbservice).

Следующим шагом в моем преобразовании, вероятно, будет подключение этих типов контроллеров в контейнере, и наряду с ними я, конечно, хотел бы зарегистрировать экземпляр IBackendWebservice, чтобы он мог автоматически разрешаться при обращении к интерфейсу. , Теперь проблема, очевидно, заключается в том, что в тот момент, когда у меня наконец есть объект IBackendWebservice, контейнер уже собран и не может принимать новые регистрации (и у меня нет ссылки на него в моем MainForm ).

Одна вещь, которая пришла мне в голову сейчас, это то, что мне, вероятно, нужно подключить фабричный делегат для класса Connection и передать его в LogonDialog, чтобы контейнер имел ссылку на объект Connection Я работаю с Но как мне тогда зарегистрировать интерфейс IBackendWebservice как свойство этого экземпляра Connection? И как я могу убедиться, что экземпляр Connection может и будет заменен, когда через диалог входа в систему будет установлено новое соединение, но не в каком-либо другом месте, где разрешается тип Connection?
Эта мысль имеет какой-то смысл вообще?

Спасибо за любые * указатели.

1 Ответ

2 голосов
/ 03 октября 2011

Вы можете сообщить о своих намерениях через дизайн, позволив LogonDialog получить зависимость от ConnectionContainer, который имеет свойство Connection.Только типы, которые могут устанавливать соединение, будут зависеть от него.Другие типы будут зависеть от Connection, как и всегда, но вы можете разрешить ее напрямую из контейнера:

builder.RegiserType<ConnectionContainer>();
builder.Register(c => c.Resolve<ConnectionContainer>().Connection).AsSelf();

(с изменением scpoing при необходимости).

...