在不同程序集中共享应用程序数据
问题描述:
我对C#/ WPF相当陌生,但这是我用于此项目的内容。在不同程序集中共享应用程序数据
让我来介绍一下上下文:我有一个允许用户登录的应用程序。我有一些基本的信息数据(物理位置)和一些动态信息(用户名...)。我用单身经理来处理所有这些事情。
该基本应用程序与两个不同的项目一起使用:登录后,应用程序必须显示当前正在运行的项目的xaml页面。
一些配置枚举允许我通过一个通用接口从正确的项目程序集实例化正确的对象(我想我应该使用WCF ...我们稍后会看到:))。
现在我需要一些由单身管理者在项目组装中处理的信息。 我该怎么办?
我不能分享单身...我应该写一个共同的数据库吗?或者摆脱单身?我有点失落。这当然是一个简单的架构问题,但我无法弄清楚。
非常感谢您的帮助!
答
我建议你使用MEF来导入和导出不同DLL的信息。每个DLL可以有资源(如XAML文件)以供查看。所以,我的选择是MVVM + MEF模块化+ Prism EventAggregator用于交互模块。 一些样品,只是一个概念演示:
'单经理' 的种类:
public class AddinsManager : IAddinsManager
{
[ImportMany(typeof(IModule))]
private OrderingCollection<IModule, IOrderMetadata> modules = new OrderingCollection<IModule, IOrderMetadata>(lazyRule => lazyRule.Metadata.Order);
private CompositionContainer container;
private bool isInitialized = false;
/// <summary>
/// Gets available application modules (add-ins)
/// </summary>
public List<IModule> Modules { get; private set; }
/// <summary>
/// Initialize manager
/// </summary>
public void Initialize()
{
Assembly oAssembly = Assembly.GetAssembly(Application.Current.GetType());
this.container = new CompositionContainer(GetCatalog(oAssembly));
this.container.ComposeParts(this, Context.Current);
this.Modules = this.modules
.Select(lazy => lazy.Value)
.ToList();
this.isInitialized = true;
}
/// <summary>
/// Initialize modules
/// </summary>
public void InitializeModules()
{
foreach (IModule oModule in this.Modules)
{
oModule.Initialize();
}
}
/// <summary>
/// Injects dependencies in specified container
/// </summary>
/// <param name="host">Container to inject in</param>
public void Compose(object host)
{
if (host == null)
{
throw new ArgumentNullException();
}
this.EnsureInitialize();
this.container.ComposeParts(host);
}
/// <summary>
/// Register views of the modules
/// </summary>
public void RegisterViews()
{
this.EnsureInitialize();
foreach (IModule oModule in this.Modules)
{
foreach (Uri oUri in oModule.GetViewPath().ToArray())
{
ResourceDictionary oDictionary = new ResourceDictionary();
oDictionary.Source = oUri;
Application.Current.Resources.MergedDictionaries.Add(oDictionary);
}
}
}
/// <summary>
/// Get catalog for modules load
/// </summary>
/// <param name="assembly">Assembly to search modules</param>
/// <returns>Catalog for modules load</returns>
private static AggregateCatalog GetCatalog(Assembly assembly)
{
string sDirName = Path.GetDirectoryName(assembly.Location);
DirectoryCatalog oDirCatalog = new DirectoryCatalog(sDirName, "Company.*");
AssemblyCatalog oAssemblyCatalog = new AssemblyCatalog(assembly);
AggregateCatalog oCatalog = new AggregateCatalog(oAssemblyCatalog, oDirCatalog);
return oCatalog;
}
/// <summary>
/// Ensure if manager was initialized
/// </summary>
private void EnsureInitialize()
{
if (!this.isInitialized)
{
throw new Exception("Add-ins Manager Component not initialized");
}
}
}
模块(DLL单独的项目)实施
[Export(typeof(IModule))]
public class LayoutsModule : AModule
{
private static LayoutsVM viewModel;
/// <summary>
/// Gets reporting add-in main view model
/// </summary>
public static LayoutsVM ViewModel
{
get
{
if (viewModel == null)
{
viewModel = Context
.Current
.LayoutManager
.ModulesVM
.OfType<LayoutsVM>()
.FirstOrDefault();
}
return viewModel;
}
}
/// <summary>
/// Initialize module
/// </summary>
public override void Initialize()
{
Context
.Current
.EventAggregator
.GetEvent<MenuInitializing>()
.Subscribe(this.InitializeMenu);
base.Initialize();
}
}
查看嵌入式资源(View.xaml )在每个DLL上。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:Company.Client.ViewModels">
<DataTemplate DataType="{x:Type vm:ApplicationVM}">
<ContentPresenter Content="{Binding AddinsViewModel}" />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:MenuVM}">
<ContentPresenter Content="{Binding RibbonData}" />
</DataTemplate>
</ResourceDictionary>
+0
由于人很多:)我不知道MEF,但它确实看起来像什么,我想实现。非常感谢 ! – Hellin
我使用MEF在我的模块导出和导入登录信息 – blindmeis