您尝试使用MVVM将我的Winform应用程序移植到WPF。我使用Caliburn Micro和MEF作为IoC。我在外部dll服务 - > Pokec_Toolki.dll ,此服务使用其他外部dll,如JSON.NET,HtmlAgilityPack..etc(第三方库)。
我的服务如下:
public interface IPokecConnection
{
PokecAccount LogOn(string nick, string password);
bool LogOff(PokecAccount account);
}
[Export(typeof(IPokecConnection))]
public class PokecConnection : IPokecConnection
{
}
对于我的服务我为类PokecConnection创建消费者,它与服务在同一个程序集中:
[Export]
public class PokecConnectionConsumer
{
private readonly IPokecConnection _pokecConn;
[ImportingConstructor]
public PokecConnectionConsumer(IPokecConnection pokecConn)
{
_pokecConn = pokecConn;
}
public PokecAccount MethodWrapperForLogOn(string name, string password)
{
return _pokecConn.LogOn(name, password);
}
}
我有2个文本框和1个按钮的简单视图。我在视图模型上将按钮的事件点击与校准惯例绑定。
查看:
<Button Micro:Message.Attach="[Event Click]=[Action LogOn(tbNick.Text,tbPassword.Text)]"
Content="Prihlás ma"
Width="100"
Grid.Row="2"
Height="25" Margin="4,4,4,4" />
我需要在视图模型中使用服务方法。所以在视图模型中我有这个:
[Export(typeof(IShellViewModel))]
public class ShellViewModel : Screen, IShellViewModel, IDataErrorInfo
{
private PokecConnectionConsumer _connConsumer;
protected override void OnInitialize()
{
base.OnInitialize();
var mycatalog = new AssemblyCatalog(System.Reflection.Assembly.LoadFrom("Pokec_Toolkit.dll"));
var container = new CompositionContainer(mycatalog);
container.ComposeParts(this);
_connConsumer = container.GetExportedValue<PokecConnectionConsumer>();
}
//this method is bind on event click of button in view
public void LogOn(string nick, string password)
{
//call method LogOn from class PokecConnection in external dll through PokecConnectionConsumer
var accout = _connConsumer.MethodWrapperForLogOn(nick, password);
// in this place if account is not null, I need close this view and create new view MainView
//a send to the MainViewModel constructor as argument variable account
//some test
MessageBox.Show(accout.SessionId);
}
}
我有这些问题:
如何关闭实际视图并创建新视图,同时激活此视图。我需要从视图模型发送作为参数变量到另一个vie模型构造函数。**
我的解决方案:
我创建了接口程序集,并在外部服务dll和wpf app中引用此程序集。
在bootstraper中,我用反射加载这个程序集:
var catalog =
new AggregateCatalog(
AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>());
catalog.Catalogs.Add(
new AssemblyCatalog(string.Format(
CultureInfo.InvariantCulture, "{0}{1}", System.IO.Directory.GetCurrentDirectory(), @"\Pokec_Toolkit.dll")));
_container = new CompositionContainer(catalog);
比我创建指挥班:
public interface IShellViewModel
{
void ShowLogOnView();
void ShowMessengerView();
}
[Export(typeof(IShellViewModel))]
public class ShellViewModel : Conductor<IScreen>, IShellViewModel
{
public ShellViewModel()
{
ShowLogOnView();
}
public void ShowLogOnView()
{
ActivateItem(IoC.Get<LogOnViewModel>());
}
public void ShowMessengerView()
{
ActivateItem(IoC.Get<MessengerViewModel>());
}
}
在视图模型中我有这个:
[Export]
public class LogOnViewModel : Screen, IDataErrorInfo, ILogOnViewModel
{
[Import]
private IShellViewModel _shellViewModel;
[Import]
private IPokecConnection _pokecConn;
//this method is bind on event click of button
public void LogOn(string nick, string password)
{
//SHOW NEW WIEW
_shellViewModel.ShowMessengerView();
}
}
答案 0 :(得分:0)
1)是的,这样如果外部依赖关系发生变化,您就不必重新编译UI。它也必须在View / VM逻辑之外。
2)我不害怕。为它创建一个单独的服务类。
3)同样,为它创建一个单独的服务类并在VM中使用。
4)好吧,无论如何你必须加载一个DLL。所以将它加载到服务类中。