0

HttContext のインスタンスを作成して StructureMap 構成に登録するにはどうすればよいですか?

私はStructureMapを使用したMVC3 Webプロジェクトを持っており、コントローラーがリポジトリクラスを呼び出し、リポジトリクラスがビジネスロジックとデータベース操作を担当する典型的な設定だと思います。

StructureMap を使用して、コントローラーに適切なリポジトリーを挿入します。

しかし最近、特定のアクションをユーザーの IP アドレスとともにログに記録するように、いくつかのリポジトリーが必要になりました。

IPアドレスを取得するために、私は使用しています

requestContext.HttpContext.Request.UserHostAddress

ここで、HttpContext をレポ クラスに渡してから、HTTContext 依存関係を StructureMap に次のように登録するのが賢明だと思いました。

For<RequestContext>().Use(ctx => HttpContext.Current.Request.RequestContext);

これはこれまでのところ機能していますが、同じリポジトリ機能を使用するミニプロジェクトもありますが、コンソールアプリケーションとして実行されます (またはサービスを獲得する可能性があります)。ここでの問題は、ASP.Net ランタイムがないと HttpContext がないことです。httpContext が null であるという実行時エラーが発生します。

そこに HttpContext を取得するにはどうすればよいですか?

編集 アレクセイとプリマスによる提案された解決策

ありがとう、アレクセイの提案を理解したら、次のようなインターフェースを作成する必要があります。

interface ILoggingConext
{
    public string IPAddress { get; set; }
}

次に、2 つの具象クラスを用意します。そのうちの 1 つ (A) は HTTPContext を受け入れ、もう 1 つ (B) は IPAddress のデフォルト値を持つことができます。

次に、StructureMap で、HttpContext が null でない場合に具象クラス a を使用するように構成します。それ以外の場合は、B を使用します。

私は近いですか?

解決

アレクセイのアドバイスを受けて、私が現在使用しているソリューションは次のとおりです。

最初にインターフェイスと 2 つの具象クラスを宣言します

public interface ILoggingContext
{
    string IPAddress { get; set; }
    string HostAddress { get; set; }
}

public class HttpLoggingContext : ILoggingContext
{
    public string IPAddress { get; set; }
    public string HostAddress { get; set; }

    //This is the concrete class to use if context is available, so provide a constructor to accept a context and set properties appropriately
    public HttpLoggingContext(RequestContext rContext)
    {
        if (rContext != null && rContext.HttpContext != null && rContext.HttpContext.Request != null)
        {
            this.IPAddress = rContext.HttpContext.Request.UserHostAddress;
            this.HostAddress = rContext.HttpContext.Request.UserHostName;
        }
    }
}

//No http context, so just set the properties to something that signifies this, using "local" here
public class ConsoleLoggingContext : ILoggingContext
{
    public string IPAddress { get; set; }
    public string HostAddress { get; set; }


    public ConsoleLoggingContext()
    {
        this.IPAddress = "local";
        this.HostAddress = "local";
    }
}

次に、StructureMap レジストリ クラスの構成を次に示します。

        For<ILoggingContext>().ConditionallyUse(o =>
            {
                o.If(c => HttpContext.Current!=null && HttpContext.Current.Request!=null && HttpContext.Current.Request.RequestContext!=null).ThenIt.Is.ConstructedBy(a=> new HttpLoggingContext(HttpContext.Current.Request.RequestContext));
                o.TheDefault.IsThis(new ConsoleLoggingContext());

            }
        ).Named("ConditionalILoggingContext");

HttpContext.Current.Request.RequestContext が null でない場合は、HttpLoggingContext を使用します。それ以外の場合は、ConsoleLoggingContext を使用します。

これを解決策としてマークしています。助けてくれてありがとう

4

2 に答える 2

2

あなたが提案するようにするには:

For<RequestContext>().Use(ctx =>
{
    //TODO: Create unittest.html as required.
    SimpleWorkerRequest request = new SimpleWorkerRequest("/unittest", @"c:\inetpub\wwwroot\unittest", "unittest.html", null, new StringWriter());
    HttpContext context = new HttpContext(request);
    return HttpContext.Current = context;
});

ただし、推奨されているように、コンテキストへの依存関係を抽象化することは、長い道のりです。

于 2013-07-09T23:03:13.343 に答える
0

私が実行した解決策は、アレクセイが提案したものでした。さまざまなラッパーを使用して、コンテキスト オブジェクトから必要なプロパティを含め、構造マップを使用して、HttpContext の存在に応じて使用するラッパーを決定します。「ソリューション」の下のサンプルコードについては、元の質問を参照してください。

于 2013-07-10T01:09:51.703 に答える