2011-12-05 26 views
6

Tôi có một mô-đun Autofac trong đó có các (tỉa xuống) logic sau đây trong Load override:Dừng Autofac mô-đun tên đăng ký lưu đã đăng ký

protected override void Load(ContainerBuilder builder) 
    { 
     foreach (var componentType in allTypesInAllAvailableAssemblies) // Set elsewhere 
     { 
      var handlerInterfaces = componentType.GetInterfaces().Where(i => i.IsClosedTypeOf(typeof(IMessageHandler<>))); 
      if (handlerInterfaces.Any()) 
       builder.RegisterType(componentType).As(handlerInterfaces); 
     } 
    } 

này đang tìm kiếm bất kỳ lớp đó tuyên bố bản thân một handler nhắn và đăng ký nó với tất cả các giao diện IMessageHandler mà nó thực hiện.

Điều tôi muốn làm là không đăng ký thành phần nếu nó đã được đăng ký. Là một phần thưởng, nó sẽ là lý tưởng nếu tôi có thể cập nhật đăng ký hiện tại để giải quyết chống lại (các) giao diện xử lý tin nhắn nếu nó chưa được.

Vì lợi ích của các đối số có thể giả định rằng mã này sẽ chạy sau tất cả các loại khác đã được đăng ký (bao gồm cả các ứng cử viên xử lý thông điệp có thể)

Tôi đã sử dụng AttachToComponentRegistration ghi đè cho các thao tác đăng ký trong quá khứ nhưng có vẻ như nó không có ích trong kịch bản này.

Điều này có thể hay tôi nên suy nghĩ lại về thiết kế và lực lượng bổ sung của mình để khai báo rõ ràng trình xử lý của họ?

+0

Bạn đã thử sử dụng lớp AnyConcreteTypeNotAlreadyRegisteredSource chưa?Xem: http://stackoverflow.com/questions/3413660/ –

Trả lời

7
builder.RegisterType(componentType) 
    .As(handlerInterfaces) 
    .PreserveExistingDefaults(); 

Sẽ hoạt động trừ khi bạn bắt đầu giải quyết danh sách xử lý.

+0

Thật không may tôi cần danh sách các trình xử lý. Tôi đã kết thúc việc thay đổi đăng ký được gửi đi để tìm kiếm tất cả các giao diện xử lý khi một loại được đăng ký rõ ràng thay vì thực hiện một lần quét khác. Chúc mừng sự giúp đỡ - Tôi đã chấp nhận điều này vì nó trả lời câu hỏi như được đăng. – JRoughan

1

Thật không may là không có cách nào thanh lịch để làm những gì bạn muốn. Thùng chứa Autofac và công cụ xây dựng của nó là "hộp đen" không cho phép bạn xem xét kỹ những gì bạn đã có.

Không có hại trong việc đăng ký thành phần hai lần, KHÔNG CẦN đăng ký của bạn phụ thuộc vào đơn đặt hàng (BAD, BAD, BAD). Đăng ký lần thứ hai sẽ chỉ ghi đè lên đăng ký cũ với mới.

Tôi nghiêm túc đặt câu hỏi mã này, vì nó phụ thuộc hoàn toàn vào cách allTypesInAllAvailableAssemblies được khởi tạo. Nếu nó thực sự là tất cả các loại trong hệ thống của bạn, sau đó nó là một crap shoot như những gì sẽ giải quyết như, nói, một IDisposable. Nếu bạn có nhiều cách triển khai khác nhau, IConfigurator, bạn sẽ có quyền kiểm soát giới hạn đối với việc đăng ký kết thúc, bất kể bạn đang kiểm tra những gì đã được đăng ký hay chỉ để đăng ký bị ghi đè; nó phụ thuộc hoàn toàn vào lớp nào kết thúc trước (hoặc cuối cùng) trong danh sách.

Điều duy nhất tôi có thể nghĩ đến làm là sử dụng một chút LINQ để đảm bảo rằng danh sách các loại bạn đang đăng ký là duy nhất:

protected override void Load(ContainerBuilder builder) 
{ 
    foreach (var componentType in allTypesInAllAvailableAssemblies.OfType<Type>().Distinct()) // Set elsewhere 
    { 
     var handlerInterfaces = componentType.GetInterfaces().Where(i => i.IsClosedTypeOf(typeof(IMessageHandler<>))); 
     if (handlerInterfaces.Any()) 
      builder.RegisterType(componentType).As(handlerInterfaces); 
    } 
} 

Điều này sẽ đảm bảo rằng mỗi trường hợp của componentType chưa bao giờ được nhìn thấy bởi người xây dựng trước đây, trong phạm vi vòng lặp foreach này. Điều đó có nghĩa rằng, cho rằng đây là module duy nhất được sử dụng để xây dựng Containers, và mỗi Container chỉ được xây dựng một lần và không bao giờ được cập nhật, mỗi thành phần trong hệ thống sẽ được đăng ký trong bất kỳ Container nào chính xác một lần. Các giao diện phổ biến, như IDisposable, IEnumerable, IComparable, IComparer, v.v. sẽ vô giá trị để cố gắng giải quyết; chúng sẽ phân giải thành một thể hiện của lớp cuối cùng có giao diện đó.

Nếu bạn phải xác minh rằng giao diện chưa bao giờ được đăng ký hoặc mã này cũng hoạt động khi sử dụng ContainerBuilder để cập nhật() Vùng chứa hiện tại, hãy dừng những gì bạn đang làm vì bạn sắp tạo ra một tuyệt vọng mess bạn sẽ không bao giờ có thể duy trì đúng cách.

+0

Điều này phát sinh bởi vì tôi có cơ chế đăng ký được gửi đôi cho các plugin (nghĩa là chúng được cung cấp một lớp hiển thị các phương thức đăng ký và nội bộ thêm chúng vào trình tạo). Điều này là tốt đẹp và sạch sẽ và có thể được sử dụng để đăng ký xử lý nhưng tôi đã tìm kiếm một cách để không buộc bổ sung đăng ký một cách rõ ràng tất cả các trình xử lý riêng của họ (bằng cách sử dụng mô-đun này trong trình bao). Điều này cũng hoạt động tốt trừ khi một thành phần được đăng ký trong công văn nhưng cũng là một trình xử lý tin nhắn (đặc biệt là nếu thời gian sống khác nhau). – JRoughan

+0

Không có vấn đề với nhiều giao diện hiện có trong hệ thống (trên thực tế nó dự kiến). Cũng không có cập nhật các thùng chứa hiện tại hoặc sự phụ thuộc vào thứ tự của các đăng ký. Tôi có lẽ đã không giải thích kịch bản cũng như tôi có thể nhưng nó không phải là xấu như bạn có thể nghĩ. – JRoughan

+0

Oh và allTypesInAllAvailableAssemblies chỉ tồn tại trong mẫu SO. Trong thế giới thực, các loại có sẵn được cung cấp bởi một lớp khác với một số thông minh trong đó. – JRoughan

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