2012-07-04 37 views
6

tôi dường như được làm điều này một chút công bằng trong mã của tôi:Tôi có ràng buộc ràng buộc các lớp bình thường bằng Autofac không?

public class ActionsModule : Module 
    { 
     protected override void Load(ContainerBuilder builder) 
     { 
      base.Load(builder); 
      builder.Register(c => LogManager.GetCurrentClassLogger()).As<ILog>().InstancePerDependency(); 

      // Autofac doesn't seem to be able to inject things without explicit binding 
      builder.RegisterType<ComboActions>().As<ComboActions>().InstancePerHttpRequest(); 
      builder.RegisterType<AppActions>().As<AppActions>().InstancePerHttpRequest(); 
     } 
    } 
} 

đâu lớp 'hành động' là một lớp I yêu cầu để được tiêm vào bộ điều khiển của tôi, và có nhiều khác phụ phụ thuộc.

Dường như một chút rác rưởi. Tại sao không thể tự động giải quyết rằng lớp có một hàm tạo với các phụ thuộc đã được thỏa mãn và tự động tạo một cá thể?

Ý tôi là, nếu lớp A yêu cầu lớp B được tiêm và lớp B yêu cầu C, D, E, vv đủ công bằng, tôi đoán bạn không muốn đi bộ toàn bộ chuỗi phụ thuộc để xem bạn có thể tạo lớp hay không trong thời gian chạy. ... nhưng nếu lớp A trực tiếp phụ thuộc vào C và D được ràng buộc rõ ràng, chắc chắn đó là một trường hợp tầm thường?

Tôi có thiếu gì đó không? Có vẻ như không thấy bất kỳ tài liệu nào về việc này ...

Trả lời

2

AFAIK, Autofac yêu cầu mọi loại cần thiết để đăng ký trong vùng chứa, nhưng điều này không có nghĩa là bạn phải thực hiện từng loại riêng lẻ. Hầu như 99% số đăng ký của tôi được xử lý bằng cách thêm thuộc tính này để loại:

[AttributeUsage(AttributeTargets.Class)] 
public class AutoRegisterAttribute : Attribute { } 

Vì vậy, ví dụ, bạn muốn có

[AutoRegister] 
class ComboActions 
{ 

Và sau đó tôi đăng ký cho họ với điều này:

public class AutoScanModule : Module 
{ 
    private readonly Assembly[] _assembliesToScan; 

    public AutoScanModule(params Assembly[] assembliesToScan) 
    { 
     _assembliesToScan = assembliesToScan; 
    } 

    protected override void Load(ContainerBuilder builder) 
    { 
     builder.RegisterAssemblyTypes(_assembliesToScan) 
      .Where(t => t.GetCustomAttributes(typeof (AutoRegisterAttribute), false).Any()) 
      .AsSelf() 
      .AsImplementedInterfaces() 
      .InstancePerLifetimeScope(); 
    } 
} 

Giống như tôi đã nói, điều này bao gồm hầu hết các đăng ký của tôi và sau đó tôi thường chỉ phải lo lắng về những thứ như loại bên thứ 3, mở generics và decorators.

EDIT: Hãy xem reply from Kaleb chứng minh rằng tôi đã sai. Tính năng tuyệt vời mà tôi chưa bao giờ biết!

20

Bạn không phải đăng ký mọi loại. Autofac cung cấp AnyConcreteTypeNotAlreadyRegisteredSource sẽ tự động lấy một loại cụ thể nếu bạn chưa cung cấp đăng ký.

Ví dụ:

var builder = new ContainerBuilder(); 
builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource()); 
var container = builder.Build(); 
... 
var myConcreteType = container.Resolve<MyConcreteType>(); 

Nguồn phép điều phức tạp hơn, như automatically injecting mocked objects cho các giao diện và phụ thuộc dựa lớp trừu tượng.

+0

Whoah. Không bao giờ biết về điều này. TIL! –

+1

đây là tuyệt vời, đặc biệt là kể từ khi bạn có thể làm một cái gì đó như 'builder.RegisterSource (new AnyConcreteTypeNotAlreadyRegisteredSource (x => x.Name.Contains (" ViewModel ")));' –

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