2013-07-09 56 views
0

如何創建HttContext的實例並在StructureMap配置中註冊它?在作爲非web應用程序運行的MVC/StructureMap項目中創建HttpContext

我使用StructureMap有,我認爲,一個典型的設置,其中控制器調用庫類和回購類負責業務邏輯和數據庫操作的MVC3 Web項目。

StructureMap用於爲控制器注入適當的存儲庫。

但最近,我需要一些回購記錄某些操作以及用戶的IP地址。

要獲取IP地址,我使用

requestContext.HttpContext.Request.UserHostAddress 

現在,我認爲這將是智能傳遞的HttpContext進入回購類,然後這樣註冊在StructureMap的HTTContext扶養:

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

這是工作,到目前爲止,但我也有一個小型的項目,將使用相同的回購功能,但運行作爲控制檯應用程序(或者服務取勝)。這裏的問題是沒有ASP.Net運行時沒有HttpContext。我得到一個運行時錯誤,說httpContext爲null。

如何在那裏獲得HttpContext?

編輯由阿列克謝和普利茅斯

建議的解決方案

感謝,如果我理解阿列克謝的建議,我應該像一個接口:

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

然後有2個具體類,一其中(A)接受一個HttpContext的,而另一個(B)可在StructureMap具有的IPAddress

一個默認值。然後,將其配置使得其瓦特如果HttpContext不爲null,則使用具體類a。否則,它將使用B.

我關閉了嗎?

SOLUTION

以阿列克謝的意見,這裏是我目前使用的解決方案:

首先聲明的接口和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不爲空,我們使用HttpLoggingContext。否則,我們使用ConsoleLoggingContext。

我將此標記爲解決方案。感謝您的幫助

+1

有特殊的接口/對象提供IP可能更合適... –

+1

在您的編輯:是的,這正是我的意思。從保護自己的角度來看,它更安全得多,以免錯誤地在代碼的其他'HttpContext'屬性上獲得額外的依賴關係。 –

回答

0

我使用的解決方案是Alexei建議的。使用不同的包裝來包含我需要的上下文對象所需的屬性,並使用結構映射根據HttpContext的存在來決定使用哪個包裝。在「解決方案」下查看原始問題的示例代碼。

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; 
}); 

正如雖然建議,在上下文抽象的依賴將是一個更好的很長的路要走。

+0

謝謝。我正在與另一種選擇,但這個選項是很好記住,因爲我甚至不知道這是可能的。 – getit

相關問題