在不同的程序集中共享应用程序

时间:2011-11-21 22:51:55

标签: c# .net wpf xaml

我是 C#/ WPF 的新手,但这是我用于此项目的内容。

让我介绍一下上下文:我有一个允许用户登录的应用程序。我有一些基本的信息数据(物理位置)和一些动态信息(用户名......)。我用单身经理处理了所有这些。

此基本应用程序与两个不同的项目一起使用:登录后,应用程序必须显示当前正在运行的项目的xaml页面。

一些配置枚举允许我通过通用接口从正确的项目程序集中实现正确的对象(我想我应该使用WCF ...我们稍后会看到:))。

现在我需要一些由单件管理器处理的信息,在项目组件中。 我该怎么办?

我无法分享单身人士......我应该写一个普通的数据库吗?还是摆脱单身?我有点迷茫。这当然是简单的架构问题,但我无法弄明白。

非常感谢你的帮助!

1 个答案:

答案 0 :(得分:1)

我建议您使用MEF导入和导出来自不同DLL的信息。每个DLL都可以拥有用于视图提供的资源(如XAML文件)。所以,我的选择是MVVM + MEF模块化+ Prism EventAggregator用于交互beetwen模块。 一些样本,仅用于概念演示:

有点'单身经理':

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();
    }
}

在每个DLL上查看为嵌入资源(View.xaml)。

<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>