gpt4 book ai didi

c# - 命名空间自定义约定 - View 和 View 模型在单独的程序集中

转载 作者:太空宇宙 更新时间:2023-11-03 11:00:54 24 4
gpt4 key购买 nike

我在名为 MyApp.Shell 的单个程序集中有 ShellView 和 ShellViewModel。

View 模型:

namespace MyApp.Shell.ViewModels
{
public class ShellViewModel : Conductor<IScreen>.Collection.AllActive, IShellViewModel
{
public IMenuViewModel Menu { get; set; }

}
}

查看:

namespace MyApp.Shell.Views
{
/// <summary>
/// Interaction logic for ShellView.xaml
/// </summary>
public partial class ShellView : Window
{
public ShellView()
{
InitializeComponent();
}
}
}

在另一个名为 MyApp.MenuViewModel 的程序集中,我有一部分 MenuViewModel。

namespace MyApp.MenuViewModel.ViewModels
{
public class MenuViewModel : Screen, IMenuViewModel
{

}
}

在名为 MyApp.MenuView 的第三个程序集中,我有一部分 MenuView。

namespace MyApp.MenuView.Views
{
/// <summary>
/// Interaction logic for MenuView.xaml
/// </summary>
public partial class MenuView : UserControl
{
public MenuView()
{
InitializeComponent();
}
}
}

我想从 ShellView 中的程序集 MyApp.MenuView 加载 MenuView。

<Window x:Class="MyApp.Shell.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ShellView" Height="600" Width="1000">
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition x:Name="rowMenu" Height="25"/>
</Grid.RowDefinitions>


<ContentControl x:Name="Menu" Grid.Row="0"/>


</Grid>
</Window>

因为命名空间不一样,我在 Bootstrap 的 Configure 方法中尝试映射命名空间:

我的目标是翻译命名空间 MyApp.MenuView.Views -> MyApp.Shell.Views

 ViewLocator.AddSubNamespaceMapping("MyApp.*.Views", "Shell");

并翻译命名空间 MyApp.MenuViewModel.ViewModels -> MyApp.Shell.ViewModels

ViewModelLocator.AddSubNamespaceMapping("MyApp.*.ViewModels", "Shell");

但是当我运行应用程序时出现错误:

找不到 MyApp.MenuViewModel.ViewModels 的 View 。菜单 View 模型

我也试过了

        ViewLocator.AddNamespaceMapping("MyApp.*.Views", "MyApp.Shell.Views");

ViewModelLocator.AddNamespaceMapping("MyApp.*.ViewModels", "MyApp.Shell.ViewModels");

怎么了?问题出在 AddSubNamespaceMapping/AddNamespaceMapping 方法中,还是这个问题的根源在其他地方?

因为如果我在程序集 MyApp.MenuView 中将命名空间 MyApp.MenuView.Views 更改为 MyApp.Shell.Views 一切正常。

谢谢

这是 Bootstrap :

也许我在错误的地方使用了 AddSubNamespaceMapping。

public class CWBootstrapper : Bootstrapper<IShellViewModel>
{
#region Fields

private IWindsorContainer _container;

#endregion

#region Methods

private IEnumerable<Assembly> LoadAssemblies(string folder)
{
var directory = new DirectoryInfo(folder);
FileInfo[] files = directory.GetFiles("*.dll", SearchOption.TopDirectoryOnly);

foreach (FileInfo file in files)
{
AssemblyName assemblyName = AssemblyName.GetAssemblyName(file.FullName);
Assembly assembly = AppDomain.CurrentDomain.Load(assemblyName);//Assembly.Load(assemblyName);
yield return assembly;
}

yield break;
}

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

_container.Register(Component
.For<IWindowManager>()
.ImplementedBy<WindowManager>()
.LifeStyle.Is(LifestyleType.Singleton));

_container.Register(Component
.For<IEventAggregator>()
.ImplementedBy<EventAggregator>()
.LifeStyle.Is(LifestyleType.Singleton));


_container.Install(new ViewModelsInstaller());
_container.Install(new ViewsInstaller());


//MyApp.MenuView.Views
ViewLocator.AddSubNamespaceMapping("MyApp.*.Views", "Shell");
//MyApp.MenuViewModel.ViewModels
ViewModelLocator.AddSubNamespaceMapping("MyApp.*.ViewModels", "Shell");

var config = new TypeMappingConfiguration
{

DefaultSubNamespaceForViews = "MyApp.Shell.Views",
DefaultSubNamespaceForViewModels = "MyApp.Shell.ViewModels",

ViewModelSuffix = "ViewModel",
ViewSuffixList = new List<string> { "View" }
};

ViewLocator.ConfigureTypeMappings(config);
ViewModelLocator.ConfigureTypeMappings(config);

}


protected override IEnumerable<Assembly> SelectAssemblies()
{
var assemblies = base.SelectAssemblies().ToList();

//load views asm from folder Views
IEnumerable<Assembly> viewsAsm = LoadAssemblies(@"Views");
//load viewmodels asm from folder ViewModel
IEnumerable<Assembly> viewModelsAsm = LoadAssemblies(@"ViewModels");

assemblies.AddRange(viewsAsm);
assemblies.AddRange(viewModelsAsm);

return assemblies;
}

protected override object GetInstance(Type service, string key)
{
return string.IsNullOrWhiteSpace(key)
? _container.Resolve(service)
: _container.Resolve(key, new { });
}

protected override IEnumerable<object> GetAllInstances(Type service)
{
return _container.ResolveAll(service).Cast<object>();
}

protected override void BuildUp(object instance)
{
instance.GetType().GetProperties()
.Where(property => property.CanWrite && property.PropertyType.IsPublic)
.Where(property => _container.Kernel.HasComponent(property.PropertyType))
.ForEach(property => property.SetValue(instance, _container.Resolve(property.PropertyType), null));
}

#endregion
}

已编辑:

我在这里上传我的解决方案:http://www.4shared.com/rar/yaPwUV6d/App.html

谁能帮帮我。我找不到问题所在。

最佳答案

好的 Kopernik,你的问题让我阅读了很多我搁置的信息。不过,您的问题可以用一行代码解决:

ViewLocator.AddSubNamespaceMapping("MyApp.MenuViewModel.ViewModels", "MyApp.MenuView.Views");

如果这不能单独工作,那么确保您正在添加/加载包含 View 的程序集(在您的情况下是MyApp.MenuView )AssemblySource.Instance 在您的 SelectAssemblies() 覆盖中正确。

问题背后的基本思想是 Caliburn.Micro 的 ViewLocator 正在寻找 MyApp.MenuViewModel.ViewModels.MenuViewMyApp.MenuViewModel.Views。 MenuView 但它找不到任何一个。

基本上我所做的是告诉 Caliburn.Micro 的 ViewLocator 在需要时用 MyApp.MenuView.Views 替换 MyApp.MenuViewModel.ViewModels搜索 View 和 wallah!它找到了。

根据我从您的代码中得出的结论,您似乎正在执行 View 模型优先导航,因此您暂时不需要其他任何东西。

最后一件事,对问题的彻底解释以及如何解决它可能需要大量解释,我真的没有时间,所以我建议您阅读 NameTransformerViewModel/View Naming Conventions文章以对此有一个很好的了解。

关于c# - 命名空间自定义约定 - View 和 View 模型在单独的程序集中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17755242/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com