2010-12-18 12 views
1

私は、私のWPFアプリケーション用にMVVMフレームワークとしてCaliburn.Mictoを使用し、注入用にもMEFを使用します。IoC-MEF注入問題

私のアプリケーションのUMLは、次のようになります。http://i54.tinypic.com/2n1b4mx.png

私のシナリオは次のとおりです。私はシェルとビューモデル-1(プロジェクトにLogOnViewModelがある)新しいビューモデル-2(私のプロジェクトでMessengerViewModelある)で作成します-view-modelメソッド。

view-model-1からview-model-2のコンストラクタにオブジェクトを渡す必要があります。

私はboostraperクラスでロードされている外部アセンブリからの注入クラスにMEFを使用します。私は私のシェル・ビュー・モデルで、このファクトリクラスを使用

/// <summary> 
/// Factory interfaces 
/// </summary> 
public interface IViewModelFactory 
{ 

    ILogOnViewModel CreateLogOnViewModel(IShellViewModel shellViewModel); 
    IMessengerViewModel CreateMessengerViewModel(IShellViewModel shellViewModel, PokecAccount account); 
} 

/// <summary> 
/// Concrent implementation of factory 
/// </summary> 
[Export(typeof(IViewModelFactory))] 
public class DefaulFactoryViewModel:IViewModelFactory 
{ 
    #region Implementation of IViewModelFactory 

    //create start up view-model 
    public ILogOnViewModel CreateLogOnViewModel(IShellViewModel shellViewModel) 
    { 
    return new LogOnViewModel(shellViewModel); 
    } 

    //this method create new view model 
    //it is used in LogOnViewModel 
    public IMessengerViewModel CreateMessengerViewModel(IShellViewModel shellViewModel, PokecAccount account) 
    { 
    return new MessengerViewModel(shellViewModel, account); 
    } 

} 

:ここで私はAbstract Factoryパターンを使用して新しいビュー・モデルの作成に

は、私の実装です。シェルビューモデルのクラスは、次のようになります。

/// <summary> 
/// Shell model interface 
/// </summary> 
public interface IShellViewModel 
{ 
    //create start up view-model 
    void ShowLogOnView(); 

    //this method create new view model 
    //it is used in LogOnViewModel 
    void ShowMessengerView(PokecAccount account); 
} 

[Export(typeof(IShellViewModel))] 
public class ShellViewModel : Conductor<IScreen>, IShellViewModel 
{ 
    //factory interface 
    private readonly IViewModelFactory _factory; 

    [ImportingConstructor] 
    public ShellViewModel(IViewModelFactory factory) 
    { 
    //inject factory 
    _factory = factory; 

    //show startup view model 
    ShowLogOnView(); 
    } 

    public void ShowLogOnView() 
    { 
    //create LogOnViewModel class with factory 
    var model = _factory.CreateLogOnViewModel(this); 

    ActivateItem(model); 
    } 

    /// <summary> 
    /// Create MessengerViewModel 
    /// </summary> 
    /// <param name="account">account in this case is send from LogOnViewModel class </param> 
    public void ShowMessengerView(PokecAccount account) 
    { 
    //create MessengerViewModel class with factory 
    var model = _factory.CreateMessengerViewModel(this, account); 

    ActivateItem(model); 
    } 
} 

} 

起動ビューモデル。 LogOnViewModelクラス:

public interface ILogOnViewModel : IScreen, IDataErrorInfo 
{ 
string Nick { get; set; } 
string Password { get; set; } 
bool CanLogOn { get; set; } 
void LogOn(string nick, string password); 
} 


public class LogOnViewModel : Screen, ILogOnViewModel 
{ 
/// <summary> 
/// inject class from external assembly 
/// after creation of this class is still null 
/// </summary> 
[Import] 
public IPokecConnection PokecConn { get; set; } 


private readonly IShellViewModel _shellViewModel = null; 

private PokecAccount _account = null; 

public LogOnViewModel(IShellViewModel shellViewModel) 
{ 
    _shellViewModel = shellViewModel; 
    _account = new PokecAccount(); 
} 


//CREATE NEW VIEW MODEL 
public void CreateNewView() 
{ 
    //create new view-model (MessengerViewModel) 
    _shellViewModel.ShowMessengerView(_account); 
} 

} 

MessengerViewModelクラス:

public interface IMessengerViewModel : IScreen 
{ 
BitmapImage AvatarImage { get; set; } 
string AvatarStatus { get; set; } 
KeyValuePair<string, Friend> SelectedFriend { get; set; } 
} 

public class MessengerViewModel : Screen, IMessengerViewModel 
{ 


[Import] 
private IPokecService _pokecService; 
[Import] 
private IPokecConnection _pokecConn; 
private IShellViewModel _shellViewModel = null; 
private PokecAccount _account = null; 

public MessengerViewModel(IShellViewModel shellViewModel, PokecAccount account) 
{ 
    _shellViewModel = shellViewModel; 
    _account = account; 
} 
} 

私はビューモデルクラスへの注入に問題があります。ビューモデルクラスの作成時に私はファクトリパターンを使用しますが、このクラスでも外部アセンブリから注入する必要があります。

例:LogOnVieModelクラスの作成後はIPokecConnectionです。PokecConn {get; set;}まだnullです。

私の場合、最も適切な解決策は何ですか?それはどこに問題がありますか?助けてくれてありがとう。

答えて

1

使用しているファクトリパターンは、ViewScreenModelクラス自体を構成する以外の構図を作成しません。注射によって作成されていない場合は、ビューモデルを作成するようにMEFに指示する必要があります。ファクトリー・クラスを更新してから、インスタンスを作成してから戻してください。 Bootstapper.ContainerCompositionContainerのインスタンスである

public ILogOnViewModel CreateLogOnViewModel 
{ 
    var model = new LogOnViewModel(); 
    var container = // set this to your reference of CompositionContainer 
    container.ComposeParts(model); 

    return model; 
} 

...。

別の理由として、使用する代わりに別のアカウントを作成した理由your current one