18

Tôi có một nhà cung cấp tư cách thành viên/vai trò tùy chỉnh mà tôi sử dụng trong bộ điều khiển MVC của mình mà tôi cũng muốn truy cập vào ASP.NET MVC, vì vậy tôi có thể sử dụng AuthorizationFilters, v.v. Vì rất nhiều người đã triển khai các nhà cung cấp tùy chỉnh, tôi tưởng tượng nhiều người đã làm điều này nhưng tôi chưa tìm ra hoặc tìm thấy các bài đăng giải quyết vấn đề này một cách cụ thể. This post là một mặt lật của câu hỏi của tôi. Trong trường hợp của tôi, tôi có nhà cung cấp tùy chỉnh của tôi làm việc tốt với các bộ điều khiển của tôi, và tôi cũng muốn MVC sử dụng nó.Làm thế nào để tích hợp nhà cung cấp thành viên IoC với ASP.NET MVC

Nhà cung cấp của tôi được triển khai với thiết kế tiêm IoC/phụ thuộc. Nhà cung cấp cho thấy chức năng bổ sung ngoài API thành viên/vai trò cơ sở. Trong bộ điều khiển của tôi, tôi sử dụng Castle Windsor để tạo các thể hiện. Mã này trông tương tự như:

public class HomeController : Controller { 
    IMembershipService _membershipService; 
    public HomeController(IMembershipService membershipService) { 
     _membershipService= membershipService; 
    } 
} 

<castle> 
<components> 
    <component id="MembershipService" 
      service="IMembershipService, MyApp" 
      type="MembershipService, MyApp" lifestyle="PerWebRequest"> 
    <parameters> 
     <connectionString>#{defaultConnectionString}</connectionString> 
    </parameters> 
    </component> 
</components> 
</castle> 

public class WindsorControllerFactory : DefaultControllerFactory { 
    private WindsorContainer _container; 
    public WindsorControllerFactory() { 
     _container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle"))); 

     List<Type> controllerTypes = new List<Type>(); 
     foreach (Type t in Assembly.GetExecutingAssembly().GetTypes()) { 
      if (typeof(IController).IsAssignableFrom(t)) 
       controllerTypes.Add(t); 
     } 

     foreach (Type t in controllerTypes) { 
      // LifestyleType.Transient = new controller instance for each request 
      _container.AddComponentLifeStyle(t.FullName, t, LifestyleType.Transient); 
     } 
    } 

    protected override IController GetControllerInstance(Type controllerType) { 
     return (IController)_container.Resolve(controllerType); 
    } 

này tất cả các công trình lớn trong mã của tôi # C nhưng tôi muốn để dây cung cấp của tôi vào MVC sử dụng [Duyệt] bộ lọc với nó:

[Authorize (Users="user1, user2", Roles="role8")] 
public ViewResult MyResult(int x) { 
    // implement 
} 

Tôi biết rằng cách thông thường để nói với ASP.NET về một thành viên tùy chỉnh hoặc nhà cung cấp vai trò là trong file web.config như dưới đây, nhưng nếu tôi làm điều này ASP.NET sẽ chỉ cố gắng gọi constructor mặc định, mà sẽ không làm việc. Bất kỳ trợ giúp nào được đánh giá cao.

<membership> 
<providers> 
    <clear/> 
    <add name="MyMembershipProvider" type="MyMembershipProvider"> 
</providers> 
</membership> 

Trả lời

24

Cách đơn giản nhất để làm việc này là sử dụng cơ chế tiêu chuẩn ASP.NET <membership> trong web.config. Bạn chỉ cần để nó sử dụng hàm tạo mặc định nhưng bạn ghi đè Khởi tạo() và kéo phụ thuộc ở đó. Sử dụng this làm tham chiếu.

Cá nhân, do những thứ như thế này, tôi muốn tránh hoàn toàn mô hình nhà cung cấp vì vậy tôi sử dụng phương pháp tương tự như cách described in the MonoRail docs. IMHO nó ít cồng kềnh và linh hoạt hơn. Cuối cùng, nó chỉ là về thiết lập HttpContext.User với một thực hiện IPrincipal thích hợp đó là những gì AuthorizeAttribute sử dụng.

Gần đây, tôi đã blogged about a solution to do proper IoC with MembershipProviders.

+1

Cảm ơn vì điều này. Trong khi phương thức đầu tiên của bạn hoạt động tốt, như bạn đã nói, việc tạo các lớp IPrincipal/IIdentity tùy chỉnh cung cấp sự linh hoạt hơn. Ví dụ: đó là một đường dẫn ngắn để tạo một số loại ủy quyền vai trò người dùng/vai trò khác với Xác thực Mẫu cung cấp. – keithm

+2

Dường như dự án webdotnet hiện đang di chuyển kho lưu trữ của nó sang mercurial, liên kết bị hỏng :-( –

+0

dự án webdotnet lên :-) –