2011-07-21 17 views
17

Hãy tha thứ cho sự thiếu hiểu biết của tôi, nhưng tôi rất mới đối với IOC và NinJect. Tôi đã tìm kiếm các giải pháp dễ hiểu và cao cho các giải pháp dễ hiểu nhưng cho đến nay họ đã bỏ qua tôi.Ninject - binding constructors với các đối số/Entity Framework connection string

Cho đến nay tôi có sau và tất cả các tác phẩm như mong đợi:

private class StandardModule : NinjectModule 
    { 
     public override void Load() 
     { 
     Bind<ILog>().To<NLogLogger>(); // Use NLog 
     Bind<IMyEntityFrameWorkRepository().To<MyEntityFrameWorkRepository>(); 
     } 
    } 

MyEntityFrameWorkRepository sau đó tạo riêng của mình EF DbContext qua một chuỗi kết nối khai báo trong app/web.config:

public class MyDbContext : DbContext 
{ 
    public MyDbContext() : base("MyAppConfig") 
    { 
    } 
    ........ 
} 

TUY NHIÊN !! Mục tiêu của tôi là một cái gì đó như thế này - Tôi nhận ra cú pháp này là "vô nghĩa" (và tôi nghĩ tôi có thể phải IOC MyDbConext quá), nhưng tôi hy vọng các "pseudo-code" truyền đạt mong muốn của tôi:

private class StandardModule : NinjectModule 
{ 
    public override void Load() 
    { 
    Bind<ILog>().To<NLogLogger>(); // Use NLog 

    string mySqlConnectionString = MyApp.GetCommandLineArgument("sqlconn"); // "Data Source=..." 
    Bind<IMyEntityFrameWorkRepository().To<MyEntityFrameWorkRepository>(mySqlConnectionString); 
    } 
} 

................. 

public class MyDbContext : DbContext 
{ 
    public MyDbContext(string sqlConnectionString) : 
     base(sqlConnectionString) // will accept a standard SQL connection string 
    { 
    } 
    ........ 
} 

Tôi thực sự sẽ đánh giá cao một số phản hồi từ các chuyên gia IOC/NinJect, vì tôi chắc chắn rằng bất kỳ "mẫu" nào có thể rất hữu ích trong các tình huống khác.

Trả lời

21

Bạn có thể sử dụng phương thức .WithConstructorArgument() để chỉ định đối số hàm tạo. Đối số đầu tiên phải là tên của tham số hàm tạo. phiên bản

public class StandardModule : NinjectModule 
{ 
    public override void Load() 
    { 
     string connectionString = "..."; 
     Bind<IMyEntityFrameWorkRepository().To<MyEntityFrameWorkRepository>() 
      .WithConstructorArgument("sqlConnectionString", connectionString); 
    } 

}

+0

TY rất nhiều! .. Tôi đã thấy cấu trúc này trong quá trình tìm kiếm của mình, nhưng vì lý do nào đó tôi luôn (nhầm lẫn) quan tâm đến "phạm vi" của 'connectionString' ... nhưng ví dụ ngắn gọn của bạn minh họa rõ ràng rằng nó chỉ là _value_ tại ràng buộc quan trọng. – JcMaltaDev

+0

là có một cách để làm điều đó mà không có chuỗi ma thuật hoặc để ninject biết mà quá tải nhưng tự quyết định nơi để có được các giá trị? – Maslow

+1

@Maslow Tôi không nghĩ rằng bạn có thể làm điều đó trong Ninject 2.2 (nhưng không dùng từ của tôi cho nó). Tuy nhiên, bạn nên đọc [bài đăng blog] này (http://www.planetgeek.ch/2011/05/28/ninject-constructor-selection-preview/) thảo luận về những thay đổi sắp tới. – mrydengren

3

mới hơn của Ninject phép để thoát khỏi chuỗi ma thuật trong định nghĩa ràng buộc. Một cái gì đó như thế này:

public class StandardModule : NinjectModule 
{ 
    public override void Load() 
    { 
     string connectionString = "..."; 
     Bind<IMyEntityFrameWorkRepository() 
      .ToConstructor(_ => new MyEntityFrameWorkRepository(connectionString); 
    } 
} 

Đối với các ràng buộc liên quan đến các loại chung (ví dụ như ràng buộc ISomeService<T>-SomeService<T> và ràng buộc nên được thực hiện cho tất cả các loại có thể cùng một lúc), ToConstructor không thể được sử dụng (một biểu hiện mới được yêu cầu), vì vậy WithConstructorArgument hài cốt cách tiếp cận đơn giản nhất. Ví dụ:

Bind(typeof(ISomeService<>)) 
    .To(typeof(SomeService<>)) 
    .WithConstructorArgument("someParam", "someValue"); 
Các vấn đề liên quan