2009-05-24 21 views
5

Tôi viết một số thư viện lớp C# và tôi muốn sử dụng Ninject để cung cấp sự phụ thuộc tiêm cho các lớp của tôi. Có thể cho libary lớp để khai báo một số mã (phương pháp) mà sẽ được thực hiện mỗi fime lớp libary được nạp. Tôi cần điều này để xác định ràng buộc cho Ninject.Phương pháp C# được thực hiện sau khi lắp ráp được nạp

Trả lời

1

Tôi đã sử dụng Ninject khá một chút trong 9 tháng qua. Âm thanh như những gì bạn cần làm là "tải" các mô-đun của bạn tồn tại trong libray của bạn vào hạt nhân Ninject để đăng ký các ràng buộc.

Tôi không chắc chắn nếu bạn đang sử dụng Ninject 1.x hoặc 2.0 beta. Hai phiên bản thực hiện mọi thứ hơi khác nhau, mặc dù khái niệm, chúng giống nhau. Tôi sẽ gắn bó với phiên bản 1.x cho cuộc thảo luận này. Một phần thông tin khác mà tôi không biết là nếu chương trình chính của bạn đang khởi tạo hạt nhân Ninject và thư viện của bạn chỉ đơn giản là thêm các ràng buộc vào hạt nhân đó, hoặc nếu chính thư viện của bạn chứa hạt nhân và các ràng buộc. Tôi giả sử rằng bạn cần thêm các ràng buộc trong thư viện của bạn vào một hạt nhân Ninject hiện có trong assembly chính. Cuối cùng, tôi sẽ giả định rằng bạn đang tự động tải thư viện này và nó không được liên kết tĩnh với chương trình chính. Điều đầu tiên cần làm là xác định một mô-đun ninject trong thư viện của bạn, trong đó bạn đăng ký tất cả các ràng buộc của bạn - bạn có thể đã làm điều này, nhưng điều đáng nói đến là vậy.Ví dụ:

public class MyLibraryModule : StandardModule { 
    public override void Load() { 
    Bind<IMyService>() 
     .To<ServiceImpl>(); 
    // ... more bindings ... 
    } 
} 

Giờ đây, các ràng buộc của bạn được chứa trong mô-đun Ninject, bạn có thể dễ dàng đăng ký chúng khi tải lắp ráp. Ý tưởng là một khi bạn tải lắp ráp của bạn, bạn có thể quét nó cho tất cả các loại có nguồn gốc từ StandardModule. Khi bạn có các loại này, bạn có thể tải chúng vào hạt nhân.

// Somewhere, you define the kernel... 
var kernel = new StandardKernel(); 

// ... then elsewhere, load your library and load the modules in it ... 

var myLib = Assembly.Load("MyLibrary"); 
var stdModuleTypes = myLib 
         .GetExportedTypes() 
         .Where(t => typeof(StandardModule).IsAssignableFrom(t)); 


foreach (Type type in stdModuleTypes) { 
    kernel.Load((StandardModule)Activator.CreateInstance(type)); 
} 

Một điều cần lưu ý là bạn có thể khái quát hóa mã trên để tải nhiều thư viện và đăng ký nhiều loại. Ngoài ra, như tôi đã đề cập ở trên, Ninject 2 có khả năng này được tích hợp sẵn - nó thực sự có khả năng quét các thư mục, các assembly tải và các mô-đun đăng ký. Rất tuyệt.

Nếu kịch bản của bạn hơi khác so với những gì tôi đã nêu, các nguyên tắc tương tự có thể được điều chỉnh.

6

Có vẻ như bạn đang tìm kiếm tương đương với DllMain của C++. Không có cách nào để làm điều này trong C#.

Bạn có thể cung cấp cho chúng tôi thêm một số thông tin về kịch bản của bạn không và tại sao bạn cần mã để thực thi theo chức năng kiểu DllMain?

Xác định hàm tạo tĩnh trên một loại không giải quyết được sự cố này. Một hàm tạo kiểu tĩnh chỉ được bảo đảm để chạy trước khi chính loại đó được sử dụng theo bất kỳ cách nào. Bạn có thể định nghĩa một hàm tạo tĩnh, sử dụng mã khác trong Dll không truy cập vào kiểu và hàm tạo của nó sẽ không bao giờ chạy.

-1

Theo tôi biết câu trả lời là không có . Vì tôi hiểu bạn muốn định cấu hình vùng chứa IoC trong thư viện lớp học của mình và nếu đó là trường hợp bạn không nên làm điều đó.Nếu bạn xác định các ràng buộc trong lớp thư viện sau đó sử dụng tiêm phụ thuộc là gì? Chúng tôi sử dụng tiêm phụ thuộc để chúng ta có thể tiêm các phụ thuộc vào thời gian chạy, sau đó chúng ta có thể tiêm các đối tượng khác nhau trong các kịch bản khác nhau.Mặc dù nơi tốt nhất để cấu hình một container IoC là khởi động ứng dụng của bạn (vì container IoC giống như một xương sống cho một ứng dụng :)) nhưng nó nên được đặt tại một bootstrap chịu trách nhiệm khởi động ứng dụng. Trong các ứng dụng đơn giản, nó có thể là phương thức chính.

+0

Có rất nhiều trường hợp bạn muốn xác định các ràng buộc trong thư viện lớp học. Bạn có khả năng có thể triển khai khác nhau của cùng một dịch vụ trong các thư viện khác nhau, cả hai đều có thể có liên quan trong cùng một ứng dụng cùng một lúc dựa trên ngữ cảnh mà dịch vụ được sử dụng. Ninject (cũng như các IoC khác) cung cấp khả năng xác định các ràng buộc theo ngữ cảnh, do đó có khả năng kích hoạt các dịch vụ cụ thể khác nhau dựa trên một số ngữ cảnh được cung cấp. –

0

Bạn có thể kiểm soát mã máy khách không? Nếu có, thay vì cố gắng để làm phép thuật khi tải lắp ráp, tôi sẽ đi để thực hiện một lớp duy nhất như Registry mà thực hiện các ràng buộc, thực hiện một giao diện IRegistry. Sau đó trong quá trình tải, bạn có thể tìm kiếm việc triển khai IRegistry trong lắp ráp của bạn và kích hoạt các phương pháp cần thiết.

Bạn cũng có thể có các thuộc tính về lớp học của bạn:

[Component(Implements=typeof(IMyDependency)] 

nhìn cho các thuộc tính và tải chúng vào container trên các mặt hàng.

Hoặc bạn có thể xem MEF là thư viện cho các loại tình huống này.

1

Bạn đã thử sự kiện AppDomain.AssemblyLoad chưa? Nó cháy sau khi một hội đồng đã được nạp.

AppDomain.CurrentDomain.AssemblyLoad += (s, e) => 
{ 
    Assembly justLoaded = e.LoadedAssembly; 
    // ... etc. 
}; 
Các vấn đề liên quan