2014-12-31 15 views
17

Tôi đã có một MVC WebAPI owin dự án (mềm lưu trữ), có sử dụng Unity để giải quyết điều khiển phụ thuộcLàm thế nào để vượt qua Owin ngữ cảnh để một Repo được tiêm vào bộ điều khiển Api

mà trông như thế này

public class PacientaiController : ODataController 
    { 
     private readonly IEntityRepo<Ent.Pacientas> repo; 

     public PacientaiController(IEntityRepo<Ent.Pacientas> repo) 
     { 
      this.repo = repo; 
     } 

vấn đề tôi đang cố gắng giải quyết - là làm cách nào để chuyển 'OwinContex' vào Repo.

public class PacientasEntityRepo:IEntityRepo<Pacientas>,IDisposable 
    { 
     public PacientasEntityRepo(IOwinContext ctx) 
     { 
     ......... 

Nếu tôi cố gắng đăng ký nó như thế này trong Startup.cs

Container.RegisterType<IOwinContext>(new InjectionFactory(o => HttpContext.Current.GetOwinContext())); 

tôi nhận được một ref null, nói rằng HttpContext.Current là NULL

Ý tưởng chính ở đây, là để vượt qua hiện người dùng đã được xác thực cho repo, vì Repo lưu trữ Logic để truy vấn Cơ sở dữ liệu, tùy thuộc vào người dùng. (nếu người dùng là Quản trị viên, sau đó trả lại dữ liệu này, nếu người dùng là khách - hãy trả lại dữ liệu này)

Vấn đề là - đây là Máy chủ tự!

+0

Bỏ qua câu trả lời của tôi, tôi đã không đọc phần * tự lưu trữ * – Jcl

+3

Tôi không thể là người duy nhất đọc và nghĩ rằng có một mùi, cụ thể là về Repo cần truy cập vào ngữ cảnh * OWIN *? Có, nó có thể cần phải thực hiện một số quyết định dựa trên người dùng hiện tại nhưng chắc chắn có được thông tin đó và chỉ lộ ra một 'IPrincipal' hoặc một cái gì đó tương tự như repo sẽ có ý nghĩa hơn? –

+1

Có thể. Nó không ảnh hưởng đến vấn đề trong anyway, gây ra tôi vẫn cần phải truy cập vào OwinContext hoặc RequestContext, đưa ra các hiệu trưởng hiện tại, và cung cấp cho nó để IoC để tiêm vào sự phụ thuộc đang được xây dựng. Không quan trọng nếu đó là một IOwinContext hoặc IPrinciple, hoặc IUserRole. Nó vẫn còn sống trong 'RequestsContext'. Câu hỏi là về các nguyên tắc giao tiếp trong tình huống tương tự hoặc tương tự. – Marty

Trả lời

21

cho phép đặt sang một bên do tại sao bạn phải thiết kế này và tập trung cho vấn đề: tiêm IOwinContext:

bạn cũng có thể lấy nó từ một trường hợp HttpRequestMessage với phương pháp GetOwinContext, tuy nhiên bạn cũng cần phải có được một HttpRequestMessage bằng cách nào đó.

Unity không hỗ trợ tiêm của HttpRequestMessage out of the box nhưng bạn có thể sử dụng một tùy chỉnh DelegatingHandler mà các cửa hàng hiện nay HttpRequestMessage trong container như đã mô tả ở đây: Inject WebAPI UrlHelper into service using Autofac

Câu hỏi liên quan là khoảng Autofac nhưng bạn có thể chuyển nó cho công việc với Unity:

các CurrentRequestCurrentRequestHandler có thể được sử dụng từ câu trả lời Andrew Davey 's vì nó là:

public class CurrentRequest 
{ 
    public HttpRequestMessage Value { get; set; } 
} 

public class CurrentRequestHandler : DelegatingHandler 
{ 
    protected async override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) 
    { 
     var scope = request.GetDependencyScope(); 
     var currentRequest = (CurrentRequest)scope.GetService(typeof(CurrentRequest)); 
     currentRequest.Value = request; 
     return await base.SendAsync(request, cancellationToken); 
    } 
} 

Sau đó, bạn chỉ cần đăng ký DelegatingHandler với:

httpConfiguration.MessageHandlers.Insert(0, new CurrentRequestHandler()); 

Và đăng ký CurrentRequestIOwinContext trong container

container.RegisterType<CurrentRequest>(
      new HierarchicalLifetimeManager()); 

container.RegisterType<IOwinContext>(
    new HierarchicalLifetimeManager(), 
    new InjectionFactory(c => c.Resolve<CurrentRequest>().Value.GetOwinContext())); 

httpConfiguration.DependencyResolver = new UnityHierarchicalDependencyResolver(container); 

Bên cạnh xử lý đoàn tùy chỉnh có những nơi khác để móc vào Web.API để chụp HttpRequestMessage ví dụ: bạn có thể tự tạo IHttpControllerActivator và sử dụng phương pháp ExecuteAsync như được mô tả tại đây: Dependency Injection in ASP.NET Web API 2

+0

Cảm ơn bạn đã đăng giải pháp sạch này. –

2

Trong ứng dụng tự lưu trữ, bạn không có HttpContext. Bạn cần một cách khác để di chuyển trạng thái xung quanh. Một lựa chọn là sử dụng một tự thực hiện HttpContext như:

https://github.com/danielcrenna/graveyard/tree/master/httpcontext-shim

+0

Tôi biết rằng không có HttpContext. Vì vậy, câu hỏi. Nhưng - có IS "OwinContext" có trong mỗi yêu cầu và trong mỗi bộ điều khiển, hành động vv .. Vấn đề là nhận được nó tại thời điểm xây dựng các phụ thuộc! – Marty

+0

Bạn có thể vượt qua ngữ cảnh xung quanh bằng cách sử dụng phép xây dựng. Tiêm owincontext vào lớp logic của bạn làm tham số hàm tạo. – Peter

1

Tôi nghĩ vấn đề là HttpContext không tồn tại vào thời điểm khởi động được gọi, vì vậy những gì bạn có thể cần, là phải có một Func thay vào đó, như thế này:

public class PacientasEntityRepo:IEntityRepo<Pacientas>,IDisposable 
{ 
    public PacientasEntityRepo(Func<IOwinContext> ctx) 
    { 
    ......... 

và sau đó thay đổi mã trong Startup này:

Container.RegisterType<IOwinContext>(new InjectionFactory(() => HttpContext.Current.GetOwinContext())); 
+1

Trong ứng dụng tự lưu trữ, bạn không có 'HttpContext' vì bạn thậm chí không tham chiếu' System.Web' để 'HttpContext.Current.GetOwinContext()' không biên dịch! Anwer của bạn chỉ có thể sử dụng nếu Web.Api được lưu trữ trong IIS nhưng OP yêu cầu một cách rõ ràng cho kịch bản tự lưu trữ. – nemesv

+0

Vâng, OP nói HttpContext là null, vì vậy tôi đoán anh ta có một tham chiếu đến System.Web, vì vậy tôi đã đặt câu hỏi –

+0

Vâng, có thể OP có kiểu HttpContext nhưng chắc chắn sẽ luôn luôn Null trong chế độ selfhosted như đã nêu trong [peer] (http://stackoverflow.com/a/27781420/872395) và cũng trong câu trả lời đã bị xóa của [Jcl] (http://stackoverflow.com/users/68972/jcl) bởi các đề xuất một giải pháp rất giống như bạn. – nemesv

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