Anwendungsdaten in verschiedenen Baugruppen gemeinsam nutzen

  • Ich bin ziemlich neu in C # / WPF , dies ist jedoch das, was ich für dieses Projekt verwendet habe.

    Lassen Sie mich Einführung in den Kontext: Ich habe eine Anwendung, mit der sich ein Benutzer anmelden kann. Ich habe einige grundlegende Informationen (physischer Ort) und einige dynamische Informationen (Benutzername ...). Ich habe das alles mit einem Singleton-Manager erledigt.

    Diese Basisanwendung wird bei zwei verschiedenen Projekten verwendet: Nach dem Anmelden muss die Anwendung xaml anzeigen Seiten für das aktuell laufende Projekt.

    Einige Konfigurationsumgebungen ermöglichen es mir, das richtige Objekt aus der richtigen Projektassembly über eine generische Schnittstelle zu instanziieren (Ich denke, ich sollte WCF verwenden ... Wir werden das später sehen :)).

    Jetzt brauche ich einige Informationen, die der Einzelmanager behandelt, in der Projektassembly. Wie kann ich das tun?

    Ich kann den Singleton nicht teilen ... Soll ich eine gemeinsame Datenbank schreiben? Oder den Singleton loswerden? Ich bin ein bisschen verloren. Dies ist sicherlich ein einfaches Architekturproblem, aber ich kann es nicht verstehen.

    Vielen Dank für Ihre Hilfe!

    22 November 2011
    JRoughan
1 answer
  • Ich empfehle Ihnen, MEF zum Importieren und Exportieren von Informationen aus verschiedenen DLLs zu verwenden. Jede DLL kann Ressourcen (wie XAML-Dateien) zum Anzeigen bereitstellen. Also, meine Wahl ist MVVM + MEF Modularität + Prism EventAggregator für die Interaktion zwischen Modulen. Einige Beispiele, nur zur Konzeptdemonstration:

    Art des 'Singleton-Managers': p>

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

    Modul (DLL für separates Projekt) Implementierung

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

    Als eingebettete Ressource (View.xaml) in jeder DLL anzeigen.

     <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>
     
    22 November 2011
    Pavel Korsukov