2009-04-09 30 views
5

Trước hết, tôi muốn lưu trữ dựa trên ngữ cảnh là nhất quán trong khuôn khổ!Tìm kiếm một kích thước phù hợp-Tất cả lưu trữ theo ngữ cảnh

Với điều đó đã nói, tôi đang tìm kiếm một giải pháp thanh lịch để làm cho các thuộc tính này an toàn trên ASP.NET, WCF và bất kỳ mã .NET đa luồng nào khác. Các thuộc tính được đặt ở một số trình trợ giúp theo dõi mức độ thấp (chúng được hiển thị thông qua các phương thức nếu bạn đang tự hỏi tại sao chúng lại là nội bộ).

Tôi không muốn phụ thuộc vào các hội đồng không cần thiết (như System.Web, v.v.). Tôi không muốn yêu cầu bất cứ ai sử dụng mã này để cấu hình bất cứ điều gì. Tôi chỉ muốn nó hoạt động;) Đó có thể là quá cao của một đơn hàng mặc dù ...

Bất cứ ai có bất kỳ thủ thuật nào lên tay áo của họ? (Tôi đã nhìn thấy thi Spring)

internal static string CurrentInstance 
    { 
     get 
     { 
      return CallContext.LogicalGetData(currentInstanceSlotName) as string; 
     } 
     set 
     { 
      CallContext.LogicalSetData(currentInstanceSlotName, value); 
     } 
    } 

    internal static Stack<ActivityState> AmbientActivityId 
    { 
     get 
     { 
      Stack<ActivityState> stack = CallContext.LogicalGetData(ambientActivityStateSlotName) as Stack<ActivityState>; 
      if (stack == null) 
      { 
       stack = new Stack<ActivityState>(); 
       CallContext.LogicalSetData(ambientActivityStateSlotName, stack); 
      } 

      return stack; 
     } 
    } 

Cập nhật

Bằng cách an toàn tôi không có nghĩa là đồng bộ. Bối cảnh về sự cố here

+0

Tôi không có nhiều để cung cấp, nhưng tôi cũng quan tâm đến vấn đề này. FWIW tôi nhớ lại nhìn thấy trong một số kho lưu trữ nguồn (có lẽ Castle, NInject, hoặc NHibernate) một số triển khai của một cái gì đó như IContext mà tôi đoán được dự định bằng DI'd vào một ứng dụng. Mỗi triển khai IContext sử dụng một công nghệ khác nhau (CallContext, HttpContext, Thread.SetData, vv). Tôi không biết chính xác chúng được sử dụng như thế nào, nhưng suy nghĩ đầu tiên của tôi là nó trừu tượng hóa "Bối cảnh". Dù sao, tôi có thể xem nếu tôi có thể tìm thấy những gì tôi tìm thấy trước và gửi một liên kết. Nó có thể hữu ích. – wageoghe

Trả lời

0

Tôi không biết rằng việc sử dụng CallContext là di chuyển đúng ở đây nếu mong muốn chỉ đơn giản là cung cấp quyền truy cập an toàn luồng cho thuộc tính của bạn. Nếu đúng như vậy, thông báo khóa là tất cả những gì bạn cần.

Tuy nhiên, bạn phải đảm bảo bạn đang áp dụng chính xác chính xác.

Với CallContext, bạn sẽ nhận được quyền truy cập an toàn chỉ vì bạn sẽ có các phiên bản CallContext riêng biệt khi các cuộc gọi đến trong các chủ đề khác nhau (hoặc các cửa hàng khác nhau). Tuy nhiên, điều đó rất khác với việc truy cập vào một luồng an toàn tài nguyên.

Nếu bạn muốn chia sẻ cùng một giá trị trên nhiều luồng, thì tuyên bố khóa là cách để đi. Nếu không, nếu bạn muốn các giá trị cụ thể trên cơ sở từng luồng/cuộc gọi, hãy sử dụng CallContext hoặc sử dụng các phương thức GetData/SetData tĩnh trên lớp Thread hoặc thuộc tính ThreadStatic (hoặc bất kỳ số lượng cơ chế lưu trữ dựa trên luồng) nào.

+0

Tôi không quan tâm đến việc đồng bộ hóa. Như bạn đã nói, chúng có nhiều cơ chế cho việc lưu trữ dựa trên bối cảnh và một số không hoạt động trong các tình huống nhất định (ví dụ: CallContext và ThreadStatic trong ASP.NET) do đó câu hỏi của tôi. – jsw

2

Dưới đây là một liên kết đến (ít nhất là một phần của) NHibernate "bối cảnh" thực hiện:

https://nhibernate.svn.sourceforge.net/svnroot/nhibernate/trunk/nhibernate/src/NHibernate/Context/

Nó không phải là rõ ràng với tôi chính xác nơi hoặc cách này đi vào chơi trong bối cảnh NHibernate. Đó là, nếu tôi muốn lưu trữ một số giá trị trong "bối cảnh" tôi sẽ nhận được "bối cảnh" từ NHibernate và thêm giá trị của tôi? Tôi không sử dụng NHibernate, vì vậy tôi không thực sự biết.

Tôi cho rằng bạn có thể xem xét và tự xác định xem loại triển khai này có hữu ích cho bạn hay không. Rõ ràng ý tưởng sẽ là để tiêm thực hiện mong muốn, tùy thuộc vào loại ứng dụng (ASP.NET, WCF, vv). Điều đó có thể ngụ ý một số cấu hình (có thể tối thiểu nếu một người sử dụng MEF để tải giao diện "ICurrentSessionContext").

Dù sao đi nữa, tôi thấy ý tưởng này thú vị khi tôi tìm thấy nó một thời gian trước khi tìm kiếm thông tin về CallContext.SetData/GetData/LogicalSetData/LogicalGetData, Thread.SetData/GetData, [ThreadStatic] vv

Ngoài ra, dựa trên việc bạn sử dụng CallContext.LogicalSetData hơn CallContext.SetData, tôi giả sử rằng bạn muốn tận dụng lợi thế của thực tế là thông tin liên quan đến luồng logic sẽ được truyền cho các chủ đề con thay vì chỉ muốn một nơi "an toàn luồng" để lưu trữ thông tin.Vì vậy, nếu bạn đã đặt (pr Push) AmbientActivity trong khởi động ứng dụng của bạn và sau đó không đẩy bất kỳ hoạt động nào nữa, bất kỳ chủ đề tiếp theo nào cũng sẽ là một phần của hoạt động đó vì dữ liệu được lưu trữ qua LogicalSetData được thừa hưởng bởi các chuỗi con.

Nếu bạn đã học bất cứ điều gì trong thời gian chờ đợi kể từ lần đầu tiên bạn đặt câu hỏi này, tôi rất muốn nghe về nó. Ngay cả khi bạn không có, tôi sẽ quan tâm đến việc tìm hiểu về những gì bạn đang làm với bối cảnh.

Hiện tại, tôi đang làm việc để duy trì một số thông tin ngữ cảnh cho ghi nhật ký/truy tìm (tương tự như Trace.CorrelationManager.ActivityId và Trace.CorrelationManager.LogicalOpertionStack và hỗ trợ ngữ cảnh log4net/NLog). Tôi muốn lưu một số bối cảnh (ứng dụng hiện tại, ví dụ ứng dụng hiện tại, hoạt động hiện tại (có thể lồng nhau)) để sử dụng trong một ứng dụng hoặc dịch vụ WCF VÀ tôi muốn truyền nó tự động qua ranh giới dịch vụ WCF. Điều này là để cho phép các khai báo đăng nhập được đăng nhập trong một kho lưu trữ trung tâm được tương quan bởi client/activity/etc. Chúng ta sẽ có thể truy vấn và tương quan cho tất cả các câu lệnh khai thác gỗ bằng một cá thể cụ thể của một ứng dụng cụ thể. Các câu lệnh đăng nhập có thể đã được tạo ra trên máy khách hoặc trong một hoặc nhiều dịch vụ WCF.

Tuyên truyền WCF của ActivityId không nhất thiết là đủ cho chúng tôi bởi vì chúng tôi muốn tuyên truyền (hoặc chúng tôi nghĩ chúng tôi làm) nhiều hơn chỉ là ActivityId. Ngoài ra, chúng tôi muốn truyền bá thông tin này từ các máy khách Silverlight tới các dịch vụ WCF và Trace.CorrelationManager không có sẵn trong Silverlight (ít nhất là không có trong 4.0, có thể một cái gì đó giống như nó sẽ có sẵn trong tương lai).

Hiện tại tôi đang tạo mẫu việc truyền bá thông tin "ngữ cảnh" của chúng tôi bằng cách sử dụng IClientMessageInspector và IDispatchMessageInspector. Có vẻ như nó sẽ hoạt động tốt cho chúng tôi.

Về sự phụ thuộc vào System.Web, triển khai NHibernate có một "ReflectiveHttpContext" sử dụng phản chiếu để truy cập HttpContext do đó sẽ không có sự phụ thuộc của dự án trên System.Web. Rõ ràng, System.Web sẽ phải có sẵn khi ứng dụng được triển khai nếu HttpContext được cấu hình để sử dụng.

Các vấn đề liên quan