0

在通過an excellent intro讀到Caliburn.Micro後,有一件事我似乎錯過了,那就是how to register a class with a constructor which is expecting arguments如何註冊IMobileServiceClient使用Caliburn.Micro.PhoneBootstrapper

有問題的行這裏是:

_container.PerRequest<IMobileServiceClient, MobileServiceClient>();

public class Bootstrapper : PhoneBootstrapper 
{ 
    private PhoneContainer _container; 

    protected override void Configure() 
    { 
     _container = new PhoneContainer(); 

     _container.RegisterPhoneServices(RootFrame); 
     _container.PerRequest<MainPageViewModel>(); 
     _container.PerRequest<IRepository, Repository>(); 
     _container.PerRequest<IMobileServiceClient, MobileServiceClient>(); 
     AddCustomConventions(); 
    } 

    //... 
} 

回答

1

我會在@flo的答案上展開一下。

當您嘗試構建的具體類型通過其構造函數接受了您已經註冊到容器的類型時,Caliburn.Micro會自動爲它提供它需要的類型以嘗試創建它。

例如,如果你有一個不接受IHell類型的對象和IHeaven類型的另外一個像這樣的命名MyClass的具體類:

public class MyClass { 
    public MyClass(IHell hell, IHeaven) { } 
} 

然後,所有你需要做的是:

container.PerRequest<IHell, ConcreteHell>(); 
container.PerRequest(IHeaven, ConcreteHeaven>(); 

現在,當Caliburn.Micro嘗試創建MyClass的實例時,它將從容器中取出IHellIHeaven

現在回到你的問題,MobileServiceClient似乎只能通過它的構造函數如string,Uri和其他類型,你不能直接註冊容器接受原始類型。

在這種情況下,你有兩個選擇:

  1. 創建一個工廠,創建MobileServiceClient S,像IMobileServiceClientFacotryMobileServiceClientFactoryImpl然後註冊那些容器,並將其注入到需要創建的MobileServiceClient實例類型並在那裏使用它們。

    這是從軟件工程角度來看更合適的解決方案,但它需要額外兩種類型的開銷。

  2. 使用Handler機制,這是用來模擬工廠註冊類型:

    container.Handler<IMobileServiceClient>(iocContainer => new MobileServiceClient("http://serviceUrl.com:34");); 
    

    該解決方案是更快,更適合當你不需要巨大的應用工廠的過度複雜性。

0

的PhoneContainer工程作爲IOC容器。這意味着,構造函數依賴關係將得到解決您的具體實例的創建:

public class MobileServiceClient : IMobileServiceClient 
{ 
private IRepository _repository; 

// repository is resolved and injected by PhoneContainer 
public MobileServiceClient (IRepository repository) 
{ 
    _repository = repository; 
} 
} 

但是如果你需要留在注射的控制。如果使用不同的LifetimeMode,您可以在Bootstrapper中配置實例:

this.container.RegisterPerRequest(
       typeof(IMultiSelectionContext), 
       null, 
       new MobileServiceClient(new RepoXy()), null)));