Click here to Skip to main content
15,892,161 members
Articles / Desktop Programming / WPF

Building WPF Applications with Self-Tracking Entity Generator - Project Setup

Rate me:
Please Sign up or sign in to vote.
4.80/5 (11 votes)
20 Feb 2012CPOL10 min read 75.7K   4.8K   54  
This article describes the project setup of building a WPF sample application with Self-Tracking Entity Generator for WPF/Silverlight.
// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
using System.ComponentModel.Composition.ReflectionModel;
using System.Reflection;
using System.ComponentModel.Composition;
using Microsoft.ComponentModel.Composition.Hosting;

namespace Microsoft.ComponentModel.Composition.Hosting
{
    public class ExportFactoryProvider : ExportProvider
    {
        static readonly IEnumerable<Export> EmptyExports = Enumerable.Empty<Export>();

        static readonly string PartCreatorContractPrefix =
            typeof(ExportFactory<>).FullName.Substring(0, typeof(ExportFactory<>).FullName.IndexOf("`"));

        ConcurrentCache<ContractBasedImportDefinition, ExportFactoryImport> _importDefinitionCache =
            new ConcurrentCache<ContractBasedImportDefinition, ExportFactoryImport>();

        ExportProvider _sourceProvider;

        public ExportProvider SourceProvider
        {
            get { return _sourceProvider; }
            set
            {
                if (value != _sourceProvider)
                {
                    if (_sourceProvider != null)
                    {
                        _sourceProvider.ExportsChanging -= SourceExportsChanging;
                        _sourceProvider.ExportsChanged -= SourceExportsChanged;
                    }

                    _sourceProvider = value;

                    if (_sourceProvider != null)
                    {
                        _sourceProvider.ExportsChanging += SourceExportsChanging;
                        _sourceProvider.ExportsChanged += SourceExportsChanged;
                    }
                }
            }
        }

        class TaggedExportsChangedEventArgs : ExportsChangeEventArgs
        {
            public TaggedExportsChangedEventArgs(object sender, IEnumerable<ExportDefinition> added, IEnumerable<ExportDefinition> removed, AtomicComposition atomicComposition)
                : base(added, removed, atomicComposition)
            {
                Sender = sender;
            }

            public object Sender { get; private set; }
        }

        void SourceExportsChanging(object sender, ExportsChangeEventArgs e)
        {
            if (SentByThis(e))
                return;

            OnExportsChanging(ProjectChangeEvent(e));
        }

        ExportsChangeEventArgs ProjectChangeEvent(ExportsChangeEventArgs e)
        {
            var satisfiedImports = _importDefinitionCache.Values;

            return new TaggedExportsChangedEventArgs(
                this,
                ProjectProductExportsIntoSatsifedCreatorExports(satisfiedImports, e.AddedExports),
                ProjectProductExportsIntoSatsifedCreatorExports(satisfiedImports, e.RemovedExports),
                e.AtomicComposition);
        }

        bool SentByThis(ExportsChangeEventArgs e)
        {
            return e is TaggedExportsChangedEventArgs &&
                ((TaggedExportsChangedEventArgs)e).Sender == this;
        }

        void SourceExportsChanged(object sender, ExportsChangeEventArgs e)
        {
            if (SentByThis(e))
                return;

            OnExportsChanged(ProjectChangeEvent(e));
        }

        IEnumerable<ExportDefinition> ProjectProductExportsIntoSatsifedCreatorExports(
            IEnumerable<ExportFactoryImport> satisfiedImports,
            IEnumerable<ExportDefinition> changedProductExports)
        {
           return from s in satisfiedImports
                from a in changedProductExports
                where s.ProductImport.IsConstraintSatisfiedBy(a)
                select s.CreateMatchingExportDefinition(a);
        }


        protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition)
        {
            if (definition == null) throw new ArgumentNullException("definition");
            if (SourceProvider == null) throw new InvalidOperationException("SourceProvider must be set.");

            var cbid = definition as ContractBasedImportDefinition;
            
            if (cbid == null || !cbid.RequiredTypeIdentity.StartsWith(PartCreatorContractPrefix))
                return EmptyExports;

            var importInfo = _importDefinitionCache.GetOrCreate(
                cbid,
                () => new ExportFactoryImport(cbid));
            
            var sourceExports = SourceProvider
                .GetExports(importInfo.ProductImport, atomicComposition);

            var result = sourceExports
                .Select(e => importInfo.CreateMatchingExport(e.Definition, SourceProvider))
                .ToArray();

            foreach (var e in sourceExports.OfType<IDisposable>())
                e.Dispose();

            return result;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
Weidong has been an information system professional since 1990. He has a Master's degree in Computer Science, and is currently a MCSD .NET

Comments and Discussions