我想知道是否有一种方法可以选择由一个 BOM 生产者生成的命名空间。我想在我的模型中为每个命名空间一一选择目标项目。
问问题
82 次
1 回答
0
Business Object Model (BOM) Producer
不允许您选择要生成的名称空间。CodeDom SubProducer
但是,您可以在将它们写入磁盘之前创建一个“删除”生成的类。以下是有关子生产者的一些示例:
- http://www.softfluent.com/documentation/webframe.html?CustomSubProducer_Topic.html
- http://blog.codefluententities.com/2013/05/16/creating-a-custom-sub-producer-to-only-generate-resources/
以下子生产者允许选择要生产的命名空间:
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 回答