1

コンソール アプリケーションで、通常は現在の http コンテキストをコンストラクターに渡す必要があるサービスを使用したいと考えています。私はNinjectを使用しています.httpコンテキストを偽造して適切なバインディングを定義するだけでよいと思います.

詳細:

このサービスは実際には、ASP.Net MVC プロジェクトに由来するメーリング サービスです。IoC にも Ninject を使用しています。メール サービスでは、現在の http コンテキストをコンストラクタに渡す必要があります。私は次のようにバインディングを行います:

kernel.Bind<IMyEmailService>().To<MyEmailService>()
    .WithConstructorArgument("httpContext", ninjectContext => new HttpContextWrapper(HttpContext.Current));

ただし、夜間に自動化されたタスクを実行するために使用されるコンソール アプリケーションでこのメール サービスを使用したいと考えています。これを行うには、単純に http コンテキストを偽造できると思いますが、これに数時間苦労しています。

コンテキストから必要なすべてのメール サービスは、次の 2 つのプロパティです。

  • httpContext.Request.UserHostAddress
  • httpContext.Request.RawUrl

私はこのようなことができると思ったが、:

独自の偽のリクエスト クラスを定義します。

public class AutomatedTaskHttpRequest : SimpleWorkerRequest
{
    public string UserHostAddress;
    public string RawUrl;

    public AutomatedTaskHttpRequest(string appVirtualDir, string appPhysicalDir, string page, string query, TextWriter output)
        : base(appVirtualDir, appPhysicalDir, page, query, output)
    {
        this.UserHostAddress = "127.0.0.1";
        this.RawUrl = null;
    }
}

独自のコンテキスト クラスを定義します。

public class AutomatedTasksHttpContext
{
    public AutomatedTaskHttpRequest Request;

    public AutomatedTasksHttpContext()
    {
        this.Request = new AutomatedTaskHttpRequest("", "", "", null, new StringWriter());
    }
}

私のコンソールアプリケーションで次のようにバインドします。

   kernel.Bind<IUpDirEmailService>().To<UpDirEmailService>()
        .WithConstructorArgument("httpContext", ninjectContext => new AutomatedTasksHttpContext());

残念ながら、これはうまくいきません。さまざまなバリエーションを試しましたが、どれも機能しませんでした。我慢してください。IoC に関するものはすべて、私にとってまったく新しいものです。

4

1 に答える 1

3

私は最近、テストにHttpContextFactoryを使用することについて回答しました。これは、コンソールアプリケーションと同じように異なるアプローチを取ります。

public static class HttpContextFactory
    {
        [ThreadStatic]
        private static HttpContextBase _serviceHttpContext;

        public static void SetHttpContext(HttpContextBase httpContextBase)
        {
            _serviceHttpContext = httpContextBase;
        }

        public static HttpContextBase GetHttpContext()
        {
            if (_serviceHttpContext!= null)
            {
                return _serviceHttpContext;
            }

            if (HttpContext.Current != null)
            {
                return new HttpContextWrapper(HttpContext.Current);
            }
            return null;
        }
    }

次に、これに対するコードで:

var rawUrl = HttpContextFactory.GetHttpContext().Request.RawUrl;

次に、テストでプロパティを継ぎ目として使用します

HttpContextFactory.SetHttpContext(HttpMocks.HttpContext());

ここで、HttpMocksには次のものがあり、テストに合わせて調整されます。

public static HttpContextBase HttpContext()
      {
          var context = MockRepository.GenerateMock<HttpContextBase>();
          context.Stub(r => r.Request).Return(HttpRequest());
          // and stub out whatever else you need to, like session etc
          return context;
      }


      public static HttpRequestBase HttpRequest()
      {
          var httpRequest = MockRepository.GenerateMock<HttpRequestBase>();
          httpRequest.Stub(r => r.UserHostAddress).Return("127.0.0.1"); 
          httpRequest.Stub(r => r.RawUrl).Return(null); 
          return httpRequest;
      }
于 2012-11-19T19:45:28.443 に答える