2011-01-29 23 views
21

Autofac tự động tạo các nhà máy cho Func<T>; Tôi thậm chí có thể truyền tham số.Ninject có hỗ trợ Func (nhà máy được tạo tự động) không?

public class MyClass 
{ 
    public MyClass(Func<A> a, Func<int, B> b) 
    { 
     var _a = a(); 
     var _b = b(1); 
    } 
} 

Tôi có thể làm tương tự với Ninject không? Nếu không, tôi có thể áp dụng giải pháp nào?

Cảm ơn.

Cập nhật:

Chỉ cần tìm thấy bài này, dường như câu trả lời là không:

How do I handle classes with static methods with Ninject?

Trả lời

29

NB Ninject 3.0 và sau đó có này hỗ trợ đầy đủ bằng cách sử dụng gói Ninject.Extensions.Factory, xem wiki: - https://github.com/ninject/ninject.extensions.factory/wiki


EDIT: NB có Bind<T>().ToFactory() triển khai trong Ninject 2.3 (không phải là bản phát hành được hỗ trợ đầy đủ thử nghiệm nhưng is available from the CodeBetter server)

Ninject không hỗ trợ điều này ngay tại thời điểm này. Chúng tôi đã lên kế hoạch để thêm nó vào phiên bản tiếp theo. Nhưng hỗ trợ có thể được thêm một cách dễ dàng bằng cách cấu hình các ràng buộc thích hợp. Chỉ cần tải các mô-đun dưới đây và thưởng thức.

public class FuncModule : NinjectModule 
{ 
    public override void Load() 
    { 
     this.Kernel.Bind(typeof(Func<>)).ToMethod(CreateFunc).When(VerifyFactoryFunction); 
    } 

    private static bool VerifyFactoryFunction(IRequest request) 
    { 
     var genericArguments = request.Service.GetGenericArguments(); 
     if (genericArguments.Count() != 1) 
     { 
      return false; 
     } 

     var instanceType = genericArguments.Single(); 
     return request.ParentContext.Kernel.CanResolve(new Request(genericArguments[0], null, new IParameter[0], null, false, true)) || 
       TypeIsSelfBindable(instanceType); 
    } 

    private static object CreateFunc(IContext ctx) 
    { 
     var functionFactoryType = typeof(FunctionFactory<>).MakeGenericType(ctx.GenericArguments); 
     var ctor = functionFactoryType.GetConstructors().Single(); 
     var functionFactory = ctor.Invoke(new object[] { ctx.Kernel }); 
     return functionFactoryType.GetMethod("Create").Invoke(functionFactory, new object[0]); 
    } 

    private static bool TypeIsSelfBindable(Type service) 
    { 
     return !service.IsInterface 
       && !service.IsAbstract 
       && !service.IsValueType 
       && service != typeof(string) 
       && !service.ContainsGenericParameters; 
    } 

    public class FunctionFactory<T> 
    { 
     private readonly IKernel kernel; 

     public FunctionFactory(IKernel kernel) 
     { 
      this.kernel = kernel; 
     } 

     public Func<T> Create() 
     { 
      return() => this.kernel.Get<T>(); 
     } 
    } 
} 
+0

Cảm ơn bạn đã viết mã! Sẽ mong chờ phiên bản tiếp theo. –

+0

Cảm ơn tất cả công việc khó khăn của bạn Remo. Có thể mở rộng mã để làm việc với Func > không? – Anders

+0

Chắc chắn rồi. Thay đổi phương thức FunctionFactory.Create, kiểm tra IEnumerable và trả về GetAll thay thế. –