1

我想知道是否有一种方法可以选择由一个 BOM 生产者生成的命名空间。我想在我的模型中为每个命名空间一一选择目标项目。

4

1 回答 1

0

Business Object Model (BOM) Producer不允许您选择要生成的名称空间。CodeDom SubProducer但是,您可以在将它们写入磁盘之前创建一个“删除”生成的类。以下是有关子生产者的一些示例:

以下子生产者允许选择要生产的命名空间:

using System;
using System.CodeDom;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Xml;
using CodeFluent.Model;
using CodeFluent.Model.Common.Design;
using CodeFluent.Model.Design;
using CodeFluent.Producers.CodeDom;
using CodeFluent.Runtime.Utilities;

namespace SelectNamespacesSubProducer
{
    [Category("Business Layer Producers")]
    [DisplayName("SubProducer Select Namespaces")]
    [Producer(Constants.SubNamespaceUri, Constants.SubProducerNamespacePrefix)]
    public class SelectNamespacesSubProducer : ICodeDomSubProducer
    {
        private CodeDomBaseProducer _baseProducer;
        private CodeFluent.Producers.CodeDom.SubProducer _subProducer;

        [Description("Determines if sub producer is enabled.")]
        [Category("Configuration")]
        [DefaultValue(true)]
        [DisplayName("Is Enabled")]
        [ModelLevel(ModelLevel.Normal)]
        public virtual bool Enabled
        {
            get
            {
                return XmlUtilities.GetAttribute(Element, "enabled", true);
            }
            set
            {
                XmlUtilities.SetAttribute(Element, "enabled", value.ToString().ToLowerInvariant());
            }
        }

        [Description("Determines the list of namespaces to produce.")]
        [Category("Configuration")]
        [DefaultValue(null)]
        [DisplayName("Namespaces")]
        [ModelLevel(ModelLevel.Normal)]
        public virtual string Namespaces
        {
            get
            {
                return XmlUtilities.GetAttribute(Element, "namespaces", (string)null);
            }
            set
            {
                XmlUtilities.SetAttribute(Element, "namespaces", value);
            }
        }

        public virtual void Initialize(CodeDomBaseProducer baseProducer, CodeFluent.Producers.CodeDom.SubProducer subProducer, IDictionary context)
        {
            _baseProducer = baseProducer;
            _subProducer = subProducer;
            baseProducer.CodeDomProduction += OnCodeDomProduction;
        }

        public virtual void Produce(IDictionary context, CodeCompileUnit unit)
        {
        }

        public virtual void Terminate(IDictionary context)
        {
        }

        private void OnCodeDomProduction(object sender, CodeDomProductionEventArgs e)
        {
            if (!Enabled)
                return;

            if (Namespaces == null)
                return;

            List<string> namespaces = ConvertUtilities.SplitToList<string>(Namespaces, ',', ';', '|');

            switch (e.EventType)
            {
                case CodeDomProductionEventType.EntityCreating:
                case CodeDomProductionEventType.SetCreating:
                case CodeDomProductionEventType.EnumerationCreating:
                    var baseType = (BaseType)e.Argument;
                    if (!namespaces.Contains(baseType.Namespace))
                    {
                        e.Cancel = true;
                        FakeProduceUnit(baseType);
                    }
                    break;
            }
        }

        private void FakeProduceUnit(BaseType baseType)
        {
            if (baseType == null)
                throw new ArgumentNullException("baseType");

            if (!_baseProducer.MustProduce(baseType, CodeFluent.Producers.CodeDom.Constants.ModelProducerNamespaceUri))
                return;

            Set set = baseType as Set;
            if (set != null)
            {
                if (!_baseProducer.MustProduce(set.ItemEntity, CodeFluent.Producers.CodeDom.Constants.ModelProducerNamespaceUri))
                    return;
            }

            // determine the final target path where the file should have gone, and pretend it's been generated
            string path = ((CodeDomProducer)_baseProducer).GetTargetPath(baseType);
            path = _baseProducer.GetProductionTargetPath(baseType, path, false, false);

            if (File.Exists(path))
            {
                _baseProducer.AddToGeneratedFiles(path);
            }
        }

        public XmlElement Element
        {
            get
            {
                if (_subProducer == null)
                    throw new CodeFluentCodeDomProducerException(GetType().FullName);

                return _subProducer.Element;
            }
            set
            {
            }
        }
    }
}

你可以这样使用它:

  <cf:producer name="Business Object Model (BOM)" typeName="CodeFluent.Producers.CodeDom.CodeDomProducer, CodeFluent.Producers.CodeDom">
    <cf:configuration compileWithVisualStudio="true" compile="false" codeDomProviderTypeName="CSharp" targetDirectory="..\Sample" cfx:targetProject="..\Sample\Sample.csproj" cfx:targetProjectLayout="Update">
      <subProducer typeName="SelectNamespacesSubProducer.SelectNamespacesSubProducer, SelectNamespacesSubProducer" 
                   namespaces="Sample.NS1, Sample.NS2" />
    </cf:configuration>
  </cf:producer>

  <cf:entity name="Customer" namespace="Sample.NS1">
    <cf:property name="Id" key="true" />
  </cf:entity>
  <cf:entity name="Order" namespace="Sample.NS2">
    <cf:property name="Id" key="true" />
  </cf:entity>
于 2015-04-13T14:25:57.383 回答