Click here to Skip to main content
12,242,812 members (43,331 online)
Click here to Skip to main content

Tagged as

Stats

16.6K views
168 downloads
25 bookmarked
Posted

Generate Proxy Class at Build Time

, 15 Nov 2011 Ms-PL
An introduction to Genuilder Extensibility
Membership.Console
bin
Debug
Membership.Console.vshost.exe
Membership.Console.vshost.exe.manifest
Release
ClassDiagram1.cd
Properties
Membership.Genuilder
bin
Debug
AppConfigVerfier.MSBuild.dll
AppConfigVerifier.dll
AppConfigVerifier.targets
AppConfigVerifier.Targets.dll
AppSettingsGenerator.targets
AppSettingsGenerator.Targets.dll
AstHelpers.dll
CommonGenerator.dll
EnvironmentFile.targets
EnvironmentFile.Targets.dll
Genuilder.Extensibility.dll
Genuilder.Extensibility.targets
InterfaceExtractor.targets
InterfaceExtractor.Targets.dll
Membership.Genuilder.vshost.exe
Membership.Genuilder.vshost.exe.manifest
PropertiesExtractor.targets
PropertiesExtractor.Targets.dll
StrongConfigGenerator.targets
StrongConfigGenerator.Targets.dll
bins
AppConfigVerfier.MSBuild.dll
AppConfigVerifier.dll
AppConfigVerifier.targets
AppConfigVerifier.Targets.dll
AppSettingsGenerator.targets
AppSettingsGenerator.Targets.dll
AstHelpers.dll
CommonGenerator.dll
EnvironmentFile.targets
EnvironmentFile.Targets.dll
Genuilder.dll
Genuilder.Extensibility.dll
Genuilder.Extensibility.NRefactory.dll
Genuilder.Extensibility.targets
ICSharpCode.NRefactory.dll
ICSharpCode.SharpDevelop.Dom.dll
InterfaceExtractor.targets
InterfaceExtractor.Targets.dll
PropertiesExtractor.targets
PropertiesExtractor.Targets.dll
StrongConfigGenerator.targets
StrongConfigGenerator.Targets.dll
Properties
ProxyGeneration
GeneratedTest.png
Genuilder.png
GenuilderInstall.png
GenuilderSite.png
IRoleProvider.png
Problem.png
ProjectTemplate.png
ProxyIRoleProviderIntelli.png
ProxyMembershipProvider.png
References.png
SecurityProxyMembershipProvider.png
SeeYouSoon.png
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Genuilder.Extensibility;
using Genuilder;
using Genuilder.Extensibility.NRefactory;
using ICSharpCode.NRefactory.Visitors;

namespace Membership.Genuilder
{
	public class ProxyGeneratorExtension : IExtension
	{
		class ProxiedInterfaceVisitor : AbstractAstVisitor
		{
			private CodeWriter writer;

			public ProxiedInterfaceVisitor(CodeWriter writer)
			{
				this.writer = writer;
			}

			public override object VisitUsing(ICSharpCode.NRefactory.Ast.Using @using, object data)
			{
				writer.WriteUsing(@using.Name);
				return base.VisitUsing(@using, data);
			}

			public override object VisitNamespaceDeclaration(ICSharpCode.NRefactory.Ast.NamespaceDeclaration namespaceDeclaration, object data)
			{
				using(writer.WriteNamespace(namespaceDeclaration.Name))
				{
					return base.VisitNamespaceDeclaration(namespaceDeclaration, data);
				}
			}

			public override object VisitTypeDeclaration(ICSharpCode.NRefactory.Ast.TypeDeclaration typeDeclaration, object data)
			{
				if(typeDeclaration.Type == ICSharpCode.NRefactory.Ast.ClassType.Interface)
				{
					var typeName = "Proxy" + typeDeclaration.Name;
					writer.Write("public class " + typeName + " : " + typeDeclaration.Name);
					writer.NewLine();
					using(writer.WriteBrackets())
					{
						writer.Write("public " + typeDeclaration.Name + " RealObject { get; private set; }");
						writer.NewLine();
						writer.Write("public " + typeName + "(" + typeDeclaration.Name + " realObject)");
						writer.NewLine();
						using(writer.WriteBrackets())
						{
							writer.Write("this.RealObject = realObject;");
						}
						return base.VisitTypeDeclaration(typeDeclaration, data);
					}

				}
				return null;
			}

			public override object VisitMethodDeclaration(ICSharpCode.NRefactory.Ast.MethodDeclaration methodDeclaration, object data)
			{
				writer.Write("public virtual " + ToName(methodDeclaration.TypeReference) + " " + methodDeclaration.Name + "(" + String.Join(", ", methodDeclaration.Parameters.Select(p => p.TypeReference + " " + p.ParameterName)) + ")");
				writer.NewLine();
				using(writer.WriteBrackets())
				{
					bool isVoid = methodDeclaration.TypeReference.Type == "System.Void";
					writer.Write((isVoid ? "" : "return ") + "RealObject." + methodDeclaration.Name + "(" + String.Join(",", methodDeclaration.Parameters.Select(p => p.ParameterName).ToArray()) + ");");
				}
				return null;
			}

			public override object VisitPropertyDeclaration(ICSharpCode.NRefactory.Ast.PropertyDeclaration propertyDeclaration, object data)
			{
				writer.Write("public virtual " + propertyDeclaration.TypeReference + " " + propertyDeclaration.Name);
				writer.NewLine();
				using(writer.WriteBrackets())
				{
					if(propertyDeclaration.HasGetRegion)
					{
						writer.Write("get");
						writer.NewLine();
						using(writer.WriteBrackets())
						{
							writer.Write("return RealObject." + propertyDeclaration.Name + ";");
						}
					}
					if(propertyDeclaration.HasSetRegion)
					{
						writer.Write("set");
						writer.NewLine();
						using(writer.WriteBrackets())
						{
							writer.Write("RealObject." + propertyDeclaration.Name + " = value;");
						}
					}
				}
				return null;
			}

			private string ToName(ICSharpCode.NRefactory.Ast.TypeReference typeReference)
			{
				if(typeReference.Type == "System.Void")
					return "void";
				return typeReference.ToString();
			}
		}
		#region IExtension Members

		public void Execute(ExtensionContext extensionContext)
		{
			var item = extensionContext.GenItems.FirstOrDefault(o => o.Name == "IRoleProvider.cs");
			item.Logger.Error("See you soon :)", 1, 5);
			if(item != null && item.Modified)
			{
				var asyncItem = item.CreateChildItem("Proxy" + item.Name);
				CodeWriter writer = new CodeWriter(asyncItem.Open());
				var itemAst = item.GetExtension<CompilationUnitExtension>();
				itemAst.ParseMethodBodies = false;
				itemAst.CompilationUnit.AcceptVisitor(new ProxiedInterfaceVisitor(writer), null);
				writer.Flush();
			}
		}

		#endregion
	}
}

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 Microsoft Public License (Ms-PL)

Share

About the Author

Nicolas Dorier
Software Developer Freelance
France France
I am currently the CTO of Metaco, we are leveraging the Bitcoin Blockchain for delivering financial services.

I also developed a tool to make IaaS on Azure more easy to use IaaS Management Studio.

If you want to contact me, go this way Smile | :)

You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160426.1 | Last Updated 15 Nov 2011
Article Copyright 2011 by Nicolas Dorier
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid