2009-02-19 37 views
7

quan trọng; Tôi là thực sự đang tìm câu trả lời StructureMap tại đây. Xin vui lòng không nói làm thế nào để làm điều đó với Windsor, Spring, Unity, hoặc bất kỳ của the others.Định cấu hình tiểu sử bằng StructureMap

Tôi đang chơi với StructureMap cho IoC - và về cơ bản mục tiêu của tôi là có tiểu sử "mặc định" xác định loại lõi và một số tiểu sử được đặt tên ghi đè/mở rộng này. Tôi nghĩ rằng rằng tiểu sử có thể làm điều này, nhưng tôi không thể làm cho nó hoạt động thông qua xml hoặc API mã. Đặc biệt, nếu tôi cố gắng tải một container cho một cấu hình:

container = new Container(); 
container.SetDefaultsToProfile(profile); 

Sau đó, tôi nhận được "yêu cầu hồ sơ {name} không thể được tìm thấy", bất chấp thực tế là tôi gọi rõ ràng CreateProfile trong initialize (với tên đó).

Tôi có đang sủa nhầm cây không?

(còn được đưa lên user-group)


Những gì tôi tưởng muốn là để có thể xác định chuẩn (/ default) loại, và sau đó cho một loạt các cấu hình được đặt tên khác nhau, override một số cài đặt - tức là nếu tôi có

  • toàn cầu: IFoo =>Foo, IBar =>Bar
  • configA: (không thay đổi)
  • configB: IFoo =>SpecialFoo

Tôi tin rằng điều này có thể lập bản đồ đến 2 container, nạp sử dụng hồ sơ đặt tên. Mục đích được rằng nếu tôi hỏi một trong hai container cho một IBar, tôi nhận được một Bar - nhưng configA trả về một Foo (ví IFoo), nơi-như configB trả về một SpecialFoo.

Ai đó có thể cho tôi biết cách tôi có thể định cấu hình điều này không? Hoặc xml hoặc mã là tốt ... Tôi chỉ muốn nó hoạt động. Tất cả những gì tôi cần là giao diện-to- ánh xạ kiểu bê tông (không có cài đặt cấu hình/thuộc tính đặc biệt).

Trả lời

9

Bí quyết là đảm bảo mọi cấu hình đơn lẻ như ít nhất một quy tắc được xác định trong đó. Nếu bạn không chỉ định quy tắc (configA) nó sẽ không tạo/xem hồ sơ.

Với những lớp:

public interface IFoo { string SayHello(); } 
public class Foo : IFoo { public string SayHello() { return "Hello"; } } 
public class SpecialFoo : IFoo { public string SayHello() { return "Hello Special"; } } 

public interface IBar { } 
public class Bar : IBar { } 

public interface IDummy { } 
public class Dummy : IDummy{ } 

Bạn có thể xác định đăng ký này:

public class MyRegistry : Registry 
{ 
    protected override void configure() 
    { 
     ForRequestedType<IBar>().TheDefault.Is.OfConcreteType<Bar>(); 
     ForRequestedType<IFoo>().TheDefault.Is.OfConcreteType<Foo>(); 
     CreateProfileNotEmpty("configA"); 
     CreateProfileNotEmpty("configB") 
      .For<IFoo>().UseConcreteType<SpecialFoo>(); 
    } 
    StructureMap.Configuration.DSL.Expressions.ProfileExpression CreateProfileNotEmpty(string profile) 
    { 
     return CreateProfile(profile) 
      .For<IDummy>().UseConcreteType<Dummy>(); 
    } 
} 

Và nó sẽ làm việc với những thử nghiệm này:

[TestMethod] 
public void TestMethod1() 
{ 
    var container = new Container(new MyRegistry()); 
    Assert.IsNotNull(container.GetInstance<IBar>()); 
    Assert.AreEqual("Hello", container.GetInstance<IFoo>().SayHello()); 

    container.SetDefaultsToProfile("configB"); 
    Assert.IsNotNull(container.GetInstance<IBar>()); 
    Assert.AreEqual("Hello Special", container.GetInstance<IFoo>().SayHello()); 

    container.SetDefaultsToProfile("configA"); 
    Assert.IsNotNull(container.GetInstance<IBar>()); 
    Assert.AreEqual("Hello", container.GetInstance<IFoo>().SayHello()); 
} 

nếu bạn thay thế CreateProfileNotEmpty với CreateProfile đơn giản , nó sẽ thất bại trên dòng thiết lập mặc định là configA.

+1

Thú vị. Tôi sẽ thử vào ngày mai. Hãy xem xét nó một +1 (và có thể là "chiến thắng") - Tôi chỉ là bỏ phiếu tại thời điểm này ;-p –

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