2010-12-18 6 views
1

저는 Caliburn.Micto를 내 WPF 응용 프로그램 용 MVVM 프레임 워크로 사용하고 주입 용 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); 
    } 

} 

: 여기에 내가 추상 팩토리 패턴을 사용하여 새 뷰 - 모델의 생성에

내 구현입니다. Shell-view-model 클래스는 다음과 같습니다.

/// <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; 
} 
} 

내가보기 모델 클래스에 주입에 문제가 있습니다. 뷰 모델 클래스를 만들 때 factory 패턴을 사용하지만 외부 어셈블리에서도이 클래스에 주입해야합니다.

예 : LogOnVieModel 클래스 생성 후 IPokecConnection입니다. PokecConn {get; 설정;} 여전히 null입니다.

내 경우 가장 적합한 솔루션은 무엇입니까? 문제가 어디에 있습니까? 도와 줘서 고마워.

답변

1

사용중인 팩터 리 패턴은 ViewScreenModel 클래스 자체를 구성하지 않고 컴포지션을 수행하지 않습니다. MEF가 사출을 통해 생성되지 않은 경우 뷰 모델을 작성하도록 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