2009-12-11 12 views
9

Tôi đang cố gắng tìm hiểu cách sử dụng IoC trong các tình huống mà các lớp phụ thuộc có thể thay đổi dựa trên một số biến trong ứng dụng trường hợp, Trạng thái phiên). Ví dụ, mỗi khách hàng của chúng tôi có một cơ sở dữ liệu khác nhau, vì vậy kết nối đến cơ sở dữ liệu cần được xây dựng trên một giá trị được lưu trữ trong phiên của họ (đặc biệt vì một số người dùng có thể có nhiều cơ sở dữ liệu nếu họ sở hữu nhiều doanh nghiệp và chuyển đổi giữa các cơ sở dữ liệu) .Cách thiết lập IoC khi một lớp khóa cần Session (hoặc biến ngữ cảnh cụ thể khác)

Dưới đây là một ví dụ chung chung về cách chúng tôi hiện đang muốn thiết lập cấu trúc này:

public class MyTestController : ControllerBase 
{ 
    Repository _rep; 

    public MyTest(Repository rep) 
    { 
     _rep = rep; 
    } 

    public MyTest() 
    { 
     string connString = String.Format("Server={0}; Database={1};" 
      , SessionContainer.ServerName, SessionContainer.DatabaseName; 
     var dc = new DataContext(connString); 
     _rep = new Repository(dc); 
    } 

    public int SampleFn() 
    { 
     return _rep.GetCountOfEmployees(); 
    } 
} 

public class Repository 
{ 
    DataContext _context; 

    public Repository(DataContext context) 
    { 
     _context = context; 
    } 
} 

chúng tôi sẽ có thể thiết lập này bằng cách sử dụng IoC và loại bỏ những mặc định c-TOR? Nếu vậy, làm thế nào? Tôi không có vấn đề gì khi sử dụng D.I. như thế này, nhưng tôi muốn khám phá khả năng của một StructureMap hoặc Unity (lưu ý: chúng ta thường chuyển trong db/server tới một lớp nhà máy xây dựng datacontext ... ví dụ trên chỉ là ngắn gọn).

Trả lời

13

Làm thế nào thể hiện Repository được tạo ra, cũng như tuổi thọ của nó, là không có mối quan tâm của Controller.

Khi bạn đăng ký thành phần trong vùng chứa, bạn nên chỉ định tuổi thọ của thành phần. Tùy thuộc vào việc triển khai của bạn, bạn có thể chỉ cần chọn đặt thời gian hoạt động của Kho lưu trữ để theo dõi phiên.

Trong mọi trường hợp, bạn có thể sử dụng một nhà máy để tạo kho lưu trữ từ phiên, nhưng thực hiện việc này từ bên ngoài Bộ điều khiển.

Bạn chắc chắn cần phải loại bỏ hàm tạo mặc định.


Tắt đầu tôi không thể nhớ cách thực hiện điều này trong Unity hoặc StructureMap, vì vậy đây là ví dụ về Castle Windsor.

Xác định một Nhà máy Tóm tắt:

public interface IRepositoryFactory 
{ 
    Repository Create(); 
} 

và một thực hiện

public class MyRepositoryFactory : IRepositoryFactory 
{ 
    private readonly HttpContextBase httpContext; 

    public MyRepositoryFactory(HttpContextBase httpContext) 
    { 
     if (httpContext == null) 
     { 
      throw new ArgumentNullException("httpContext"); 
     } 

     this.httpContext = httpContext; 
    } 

    #region IRepositoryFactory Members 

    public Repository Create() 
    { 
     // return Repository created from this.httpContext 
    } 

    #endregion 
} 

Bây giờ đăng ký tất cả những thứ

container.AddFacility<FactorySupportFacility>(); 
container.Register(Component.For<IRepositoryFactory>() 
    .ImplementedBy<MyRepositoryFactory>() 
    .LifeStyle.PerWebRequest); 
container.Register(Component.For<Repository>() 
    .UsingFactory((IRepositoryFactory f) => f.Create()) 
    .LifeStyle.PerWebRequest); 

Ở đây tôi đã sử dụng lối sống PerWebRequest, nhưng nếu bạn muốn tối ưu hóa bạn có thể muốn tạo ra một lối sống PerWebSession tùy chỉnh. Đây không phải là quá khó để làm trong lâu đài, nhưng tôi không thể nhớ nó cứng như thế nào trong các thùng chứa DI khác.

Bạn cũng sẽ cần phải đăng ký HttpContextBase, vì MyRepositoryFactory phụ thuộc vào nó.

+0

Đánh dấu - bạn có thể cụ thể hơn hoặc cung cấp ví dụ không? Chúng ta có thể có nhiều đối tượng kho lưu trữ, tất cả đều cần sử dụng cùng một DataContext (để xử lý giao dịch thích hợp). Tôi không có vấn đề đăng ký này trong container IoC khi "DataContext" sử dụng một chuỗi kết nối đó là toàn cầu hoặc được định nghĩa trong container, nhưng những gì về khi chuỗi kết nối là trong phiên của người dùng? Tôi cảm thấy như tôi đang thiếu một cái gì đó hiển nhiên. –

+0

Đã thêm ví dụ vào câu trả lời của tôi. –

+0

Ah ha, tôi nghĩ rằng tôi nhận được nó ngay bây giờ! =) Tôi đã bỏ phiếu cho bạn để tôi có thể thăng cấp bạn vào ngày mai để giành chiến thắng gấp đôi. Phản ứng tuyệt vời. –

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