2013-04-16 18 views
5

Tôi có một giao diện chung IRepository<T> và hai triển khai xrmRepository<T>efRepository<T>Ninject theo ngữ cảnh Binding w/Open Generics

Tôi muốn thay đổi các ràng buộc dựa trên T, cụ thể hơn sử dụng xrmRepository khi T xuất phát từ Entity. Làm thế nào tôi có thể thực hiện điều đó?

Tôi hiện có:

kernel.Bind(typeof(IRepository<>)).To(typeof(efRepository<>)).InRequestScope(); 
kernel.Bind(typeof(IRepository<>)).To(typeof(xrmRepository<>)).When(request => request.Service.GetGenericArguments()[0].GetType().IsSubclassOf(typeof(Entity))).InRequestScope(); 

Nhưng khi tôi cố gắng giải quyết IRepository<Contact> nó đi để efRepository, mặc dù Liên hệ thừa hưởng Entity.

Tôi không muốn sử dụng Ràng buộc có tên khác nếu không, tôi sẽ phải thêm tên ở mọi nơi.

Trả lời

2

Bạn cũng có thể xác định các ràng buộc như thế này. Tôi không biết về hiệu suất thời gian chạy, nhưng tôi nghĩ rằng nó dễ đọc hơn theo cách này. Và nếu tôi không bỏ lỡ một cái gì đó nó sẽ dẫn đến hành vi tương tự.

kernel.Bind(typeof(IRepository<>)) 
     .To(typeof(efRepository<>)) 
     .InRequestScope(); 

kernel.Bind<IRepository<Entity>>() 
     .To<xrmRepository<Entity>>() 
     .InRequestScope(); 

Sửa

Nếu mục tiêu là sử dụng xrmRepository cho mỗi lớp kế thừa từ Entity này nên làm các trick

kernel.Bind(typeof(IRepository<>)) 
        .To(typeof(XrmRepository<>)) 
        .When(request => typeof(Entity).IsAssignableFrom(request.Service.GetGenericArguments()[0])); 
+0

Không hoạt động bằng lớp cơ sở "Pháp nhân". Vẫn còn ràng buộc với efRepository. Không hoạt động nếu sử dụng chính lớp đó (như Liên hệ). –

+0

Bạn có muốn phân giải IRepository thành xrmRepository cho tất cả các lớp con của Thực thể không? – treze

+0

Đúng! Nhưng tôi có lẽ sẽ kết thúc việc tạo ra một IXRMRepository: IRepository thay vì kể từ khi tôi không thể làm cho nó hoạt động. –

1

Sử dụng phương thức When để khai báo điều kiện ràng buộc. Ví dụ được đưa ra bên dưới

kernel.Bind(typeof(IRepository<>)) 
     .To(typeof(efRepository<>)) 
     .When(request => request.Service.GetGenericArguments()[0] == typeof(Entity)) 
     .InRequestScope(); 

kernel.Bind(typeof(IRepository<>)) 
     .To(typeof(xrmRepository<>)) 
     .InRequestScope(); 

kernel.Get<IRepository<Entity>>(); //will return efRepository<Entity> 

kernel.Get<IRepository<int>>(); //will return xrmRepository<int> 
+0

vẫn gặp lỗi "GenericArguments [0], 'sf2015 .Infrastructure.Xrm.Contact ', trên' sf2015.Repositories.sfRepository'1 [T] 'vi phạm ràng buộc của tham số kiểu' T '. ". Thông tin bổ sung: f2015.Infrastructure.Xrm.Contact thuộc loại Microsoft.Xrm.Sdk.Entity. Tôi đã phải thay đổi First() thành [0] và xrmRepository là một trong những nghĩa vụ phải ràng buộc với Entity. Xem câu hỏi được cập nhật. –

+0

@JoaoLeme cung cấp các định nghĩa giao diện và cách triển khai của chúng. Cũng cung cấp cho các ví dụ về gọi ** Nhận ** và kết quả mong đợi –

+0

Khi gọi Nhận từ Mô-đun mới, nó hoạt động nếu tôi sử dụng ... GetGenericArguments(). First() == typeof (Contact) ... và gọi kernel.Get >(); nhưng nếu tôi thay thế liên hệ trên ràng buộc bởi thực thể lớp kế thừa của nó và gọi kernel.Get >() Tôi nhận được cùng một lỗi. Bằng cách này, làm cùng một trick trick (thay thế Entity by Contact) dưới RegisterServices trong NinjectWebCommon không hoạt động (Eitherway cho tôi lỗi tương tự). –