www.pudn.com > Websharp2005.rar > AbstractAssemblyGenerator.cs


using System;  
using System.Xml;  
using System.Reflection;  
using System.CodeDom;  
using System.CodeDom.Compiler;  
using Microsoft.CSharp;  
using System.IO;  
using System.Collections.Specialized;  
  
namespace Websharp.Enterprise  
{  
	///   
	/// Summary of AbstractAssemblyGenerator   
	///   
	public abstract class AbstractAssemblyGenerator : IAssemblyGenerator  
	{  
		public AbstractAssemblyGenerator(string serviceName, Type clientInterface)  
		{  
			ServiceName = serviceName;  
			ClientInterface = clientInterface;  
			CompileUnit = new CodeCompileUnit();  
			TempAssemblyNameSpace = new CodeNamespace(EnterpriseConfig.TempCreatedAssemblyNameSpace);  
			ClassName = "_Impl_"+clientInterface.Name;  
			ReferencedAssemblies = new StringCollection();  
		}  
  
		protected string serviceName;  
		public string ServiceName  
		{  
			get{return serviceName;}  
			set{serviceName=value;}  
		}  
  
		protected Type clientInterface;  
		public Type ClientInterface  
		{  
			get{return clientInterface;}  
			set{clientInterface = value;}  
		}  
  
		protected CodeCompileUnit compileUnit;  
		public CodeCompileUnit CompileUnit  
		{  
			get{return compileUnit;}  
			set{compileUnit = value;}  
		}  
  
		protected CodeNamespace tempdAssemblyNameSpace;  
		public CodeNamespace TempAssemblyNameSpace  
		{  
			get{return tempdAssemblyNameSpace;}  
			set{tempdAssemblyNameSpace = value;}  
		}  
		  
		protected StringCollection referencedAssemblies;  
		public StringCollection ReferencedAssemblies  
		{  
			get{return referencedAssemblies;}  
			set{referencedAssemblies = value;}  
		}  
  
		protected string className;  
		public string ClassName  
		{  
			get{return className;}  
			set{className = value;}  
		}  
		  
		protected bool isSingleton = false;  
		public bool IsSingleton  
		{  
			get{return isSingleton;}  
		}  
  
		public virtual Type GenerateType()  
		{  
			if(CreatedTypes.Contains(serviceName))  
			{  
				return CreatedTypes.GetType(serviceName);  
			}  
			string nodeExpr = "Service[@name='"+serviceName+"']";  
			XmlNode root = EnterpriseConfig.GetEnterpriseConfigRoot();  
			XmlNode serviceNode = root.SelectSingleNode("Services").SelectSingleNode(nodeExpr);  
  
			if((serviceNode.Attributes["deploy-model"]!=null) &&  
				(serviceNode.Attributes["deploy-model"].Value.ToLower().Equals("singleton")))  
			{  
				isSingleton = true;  
			}  
  
			InitParameter(serviceNode);			  
			return GetGeneratedType();  
		}  
  
		protected abstract void InitParameter(XmlNode serviceNode);  
		protected virtual Type GetGeneratedType()  
		{  
			Assembly createdAssembly = CreateProxyClassAssembly();			  
			return createdAssembly.GetType(TempAssemblyNameSpace.Name+"."+ClassName);  
		}  
  
		protected virtual Assembly CreateProxyClassAssembly()  
		{  
			AddReferences(clientInterface);  
			CodeTypeDeclaration generateClass = CreateClass();  
			TempAssemblyNameSpace.Types.Add(generateClass);					  
			CompileUnit.Namespaces.Add(TempAssemblyNameSpace);  
  
			CodeDomProvider provider = new CSharpCodeProvider();  
#if DEBUG  
			OutputSourceCode(compileUnit,provider,ClassName);  
#endif  
			ICodeCompiler compiler = provider.CreateCompiler();  
			CompilerParameters cp = new CompilerParameters();  
//			cp.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);  
			foreach(string refassembly in ReferencedAssemblies)  
				cp.ReferencedAssemblies.Add(refassembly);  
  
			cp.GenerateInMemory = true;  
			cp.IncludeDebugInformation = false;  
			//cp.OutputAssembly=tempAssembly+".dll";  
  
			CompilerResults results = compiler.CompileAssemblyFromDom(cp,compileUnit);  
			return results.CompiledAssembly;  
		}  
  
		protected abstract CodeTypeDeclaration CreateClass();  
  
		protected void AddReferences(Type t)  
		{  
			if(!ReferencedAssemblies.Contains(t.Assembly.Location))  
				ReferencedAssemblies.Add(t.Assembly.Location);  
			if((!t.IsInterface) && (!Object.Equals(t.BaseType,null)) && (!t.BaseType.Equals(typeof(object))))  
				AddReferences(t.BaseType);  
			foreach(Type it in t.GetInterfaces())  
				AddReferences(it);  
			if(t.IsArray)  
				AddReferences(t.GetElementType());  
  
		}  
  
		protected void OutputSourceCode(CodeCompileUnit compileUnit,CodeDomProvider provider,string strClassName)  
		{  
			ICodeGenerator gen = provider.CreateGenerator();  
			StreamWriter writer = new StreamWriter(@"e:\temp\"+strClassName+".cs",false);  
			CodeGeneratorOptions cop = new CodeGeneratorOptions();  
			cop.IndentString="	";  
			cop.BracingStyle = "C";  
			gen.GenerateCodeFromCompileUnit(compileUnit,writer,cop);  
			writer.Close();  
		}  
	}  
}