простой инжектор - внедрить в IHttpHandler - PullRequest
0 голосов
/ 12 ноября 2018

Я пытаюсь встроить SimpleInjector в мой проект WCF (я следовал инструкциям здесь ). До сих пор все шло хорошо, кроме вопроса IHttpHandler: текущая реализация использует IHttpHandler, который в свою очередь использует статический экземпляр MyServiceWrapper:

public class IsAliveHandler : IHttpHandler
{
    private const string SERVER_ERROR = "Bad";
    private const string SERVER_OK = "OK";

    public void ProcessRequest(HttpContext context)
    {
        var quoteSucceeded = false;
        var isLastLoginSucceeded = MyServiceWrapperContainer.Manager.IsLastLoginSucceeded;
//More logic here ...
    }
}

Теперь, так как я переместил свое приложение для использования механизма DI SimpleInjector, я не могу использовать такой статический доступ, так как я хочу использовать тот же экземпляр, который содержится в контейнере DI. инжекция конструктора здесь получает исключение:

[MissingMethodException: Constructor on type '***.Applications.MyServiceWrapperService.KeepAliveHandler.IsAliveHandler' not found.]

Есть ли способ использовать контейнер в таком сценарии? Есть ли альтернативы?

В общем, я могу понять, что такая проблема - запах использования состояния, но в настоящее время это требование.

1 Ответ

0 голосов
/ 12 ноября 2018

Ваш IsAliveHandler не может иметь никаких аргументов конструктора (это ограничение вашей прикладной среды).

Вместо этого вы должны сделать IsAliveHandler a Humble Object исчитайте это частью вашего корня композиции .

Это означает, что вы извлекаете всю интересную логику из IsAliveHandler (например, в IsAliveService) и меняете IsAliveHandler начто-то вроде следующего:

public class IsAliveHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        Bootstrapper.Container.GetInstance<IsAliveService>().Process(context);
    }
}

Другими словами, единственное, что вы позволяете IsAliveHandler делать, это запрашивать службу из контейнера DI и вызывать соответствующий метод для этой разрешенной службы.

Обратите внимание, что IsAliveHandler должен оставаться полностью без сохранения состояния: разрешение IsAliveService нигде не должно храниться.Вы должны оставить его до контейнера DI, чтобы предоставить вам правильный экземпляр.

В случае, если эта операция выполняется вне контекста простого инжектора Scope, вы можете заключить операцию в такой Scope:

public void ProcessRequest(HttpContext context)
{
    using (AsyncScopedLifestyle.BeginScope(Bootstrapper.Container))
        Bootstrapper.Container.GetInstance<IsAliveService>().Process(context);
}
...