Many sharepoint classes are not available to inherit from because the default contructor is hidden. The following (quick and untested!) code uses the CodeDom to generate a wrapper class.
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Reflection;
using Microsoft.SharePoint;
namespace DevHoleDemo.ClassWrapper
{
class Program
{
static void Main(string[] args)
{
ClassWrapper w = new ClassWrapper("DevHoleDemo", "SPWebWrapper", typeof(SPWeb));
string s = w.GetCode();
}
}
public class ClassWrapper
{
string m_namespace;
string m_className;
SortedDictionary<string, int> m_imports;
SortedDictionary<string, int> m_modules;
StringBuilder m_sb;
Type m_t;
public ClassWrapper(string targetNamespace, string targetClassName, object source)
: this(targetNamespace, targetClassName, source.GetType())
{
}
public ClassWrapper(string targetNamespace, string targetClassName, Type t)
{
m_namespace = targetNamespace;
m_className = targetClassName;
m_t = t;
m_imports = new SortedDictionary<string, int>();
m_modules = new SortedDictionary<string, int>();
}
public string GetCode()
{
return GetCode("CS");
}
public string GetCode(string language)
{
Generate(language);
string results = m_sb.ToString();
results = results.Replace("void implicit_operator_", "implicit operator ");
return results;
}
protected void AddNamespace(Type t)
{
if (m_imports.ContainsKey(t.Namespace))
m_imports[t.Namespace]++;
else
m_imports.Add(t.Namespace, 1);
if (m_modules.ContainsKey(t.Module.Name))
m_modules[t.Module.Name]++;
else
m_modules.Add(t.Module.Name, 1);
}
protected CodeTypeReference GetCodeTypeReference(Type t)
{
AddNamespace(t);
if (t.IsByRef)
return new CodeTypeReference(t.Name.TrimEnd('&'));
else
return new CodeTypeReference(t);
}
protected void Generate(string language)
{
m_sb = new StringBuilder();
TextWriter tw = new StringWriter(m_sb);
CodeDomProvider cdp = CodeDomProvider.CreateProvider(language);
CodeTypeReferenceExpression tre = new CodeTypeReferenceExpression(m_t);
//namespace
CodeNamespace ns = new CodeNamespace(m_namespace);
//class
CodeTypeDeclaration class1 = new CodeTypeDeclaration(m_className);
ns.Types.Add(class1);
class1.IsClass = true;
//base object field
CodeMemberField cmf1 = new CodeMemberField(GetCodeTypeReference(m_t), "m_" + m_t.Name);
class1.Members.Add(cmf1);
//constructor
CodeConstructor cc = new CodeConstructor();
cc.Attributes = MemberAttributes.Public;
CodeParameterDeclarationExpression cpde1 = new CodeParameterDeclarationExpression(GetCodeTypeReference(m_t), m_t.Name);
cc.Parameters.Add(cpde1);
CodeFieldReferenceExpression cfre1 = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_" + m_t.Name);
cc.Statements.Add(new CodeAssignStatement(cfre1, new CodeArgumentReferenceExpression(m_t.Name)));
class1.Members.Add(cc);
//methods
foreach (MethodInfo mi in m_t.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy))
{
if (!mi.IsSpecialName)
{
CodeMemberMethod meth = new CodeMemberMethod();
meth.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
meth.Attributes |= MemberAttributes.Public;
if ((mi.Attributes & MethodAttributes.Static) == MethodAttributes.Static)
meth.Attributes |= MemberAttributes.Static;
if ((mi.Attributes & MethodAttributes.Virtual) != MethodAttributes.Virtual)
meth.Attributes |= MemberAttributes.Final;
meth.Name = mi.Name;
List<CodeExpression> prms = new List<CodeExpression>();
foreach (ParameterInfo ri in mi.GetParameters())
{
CodeParameterDeclarationExpression cpde2 = new CodeParameterDeclarationExpression(GetCodeTypeReference(ri.ParameterType), ri.Name);
CodeArgumentReferenceExpression care1 = new CodeArgumentReferenceExpression(ri.Name);
CodeDirectionExpression cde = null;
if (ri.IsOut)
{
cpde2.Direction = FieldDirection.Out;
cde = new CodeDirectionExpression(FieldDirection.Out, care1);
}
meth.Parameters.Add(cpde2);
if (cde == null)
prms.Add(care1);
else
prms.Add(cde);
}
CodeMethodReferenceExpression cmre1;
if ((mi.Attributes & MethodAttributes.Static) == MethodAttributes.Static)
cmre1 = new CodeMethodReferenceExpression(tre, mi.Name);
else
cmre1 = new CodeMethodReferenceExpression(cfre1, mi.Name);
if (mi.ReturnType == typeof(void))
{
meth.Statements.Add(new CodeMethodInvokeExpression(cmre1, prms.ToArray()));
}
else
{
meth.Statements.Add(new CodeMethodReturnStatement(new CodeMethodInvokeExpression(cmre1, prms.ToArray())));
}
meth.ReturnType = GetCodeTypeReference(mi.ReturnType);
class1.Members.Add(meth);
}
}
//properties
foreach (PropertyInfo pi in m_t.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy))
{
CodeMemberProperty prop = new CodeMemberProperty();
prop.Name = pi.Name;
prop.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
prop.Attributes |= MemberAttributes.Public | MemberAttributes.Final;
List<CodeExpression> indices = new List<CodeExpression>();
if (pi.GetIndexParameters().Length > 0)
{
foreach (ParameterInfo pii in pi.GetIndexParameters())
{
CodeParameterDeclarationExpression cpde3 = new CodeParameterDeclarationExpression(GetCodeTypeReference(pii.ParameterType), pii.Name);
prop.Parameters.Add(cpde3);
CodeArgumentReferenceExpression care3 = new CodeArgumentReferenceExpression(pii.Name);
indices.Add(care3);
}
}
prop.Type = GetCodeTypeReference(pi.PropertyType);
prop.HasGet = pi.GetGetMethod() != null;
if (prop.HasGet)
{
if (pi.GetIndexParameters().Length > 0)
prop.GetStatements.Add(new CodeMethodReturnStatement(new CodeArrayIndexerExpression(cfre1, indices.ToArray())));
else
prop.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(cfre1, pi.Name)));
}
prop.HasSet = pi.GetSetMethod() != null;
if (prop.HasSet)
{
if (pi.GetIndexParameters().Length > 0)
prop.SetStatements.Add(new CodeAssignStatement(new CodeArrayIndexerExpression(cfre1, indices.ToArray()), new CodePropertySetValueReferenceExpression()));
else
prop.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(cfre1, pi.Name), new CodePropertySetValueReferenceExpression()));
}
class1.Members.Add(prop);
}
//implicit casts
CodeMemberMethod castFrom = new CodeMemberMethod();
castFrom.Name = "implicit_operator_" + m_t.Name;
castFrom.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
castFrom.Attributes |= MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static;
CodeParameterDeclarationExpression cpde4 = new CodeParameterDeclarationExpression(new CodeTypeReference(m_className), m_className);
castFrom.Parameters.Add(cpde4);
CodeArgumentReferenceExpression care4 = new CodeArgumentReferenceExpression(m_className);
CodeFieldReferenceExpression cfre3 = new CodeFieldReferenceExpression(care4, "m_" + m_t.Name);
castFrom.Statements.Add(new CodeMethodReturnStatement(cfre3));
castFrom.ReturnType = new CodeTypeReference(typeof(void));
class1.Members.Add(castFrom);
CodeMemberMethod castTo = new CodeMemberMethod();
castTo.Name = "implicit_operator_" + m_className;
castTo.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
castTo.Attributes |= MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static;
CodeParameterDeclarationExpression cpde5 = new CodeParameterDeclarationExpression(new CodeTypeReference(m_t), m_t.Name);
castTo.Parameters.Add(cpde5);
CodeArgumentReferenceExpression care5 = new CodeArgumentReferenceExpression(m_t.Name);
CodeObjectCreateExpression coce = new CodeObjectCreateExpression(new CodeTypeReference(m_className), care5);
castTo.Statements.Add(new CodeMethodReturnStatement(coce));
castTo.ReturnType = new CodeTypeReference(typeof(void));
class1.Members.Add(castTo);
//write imports
foreach (KeyValuePair<string, int> kvp in m_imports)
{
ns.Imports.Add(new CodeNamespaceImport(kvp.Key));
}
//write modules comments
ns.Comments.Add(new CodeCommentStatement("References to the following modules must be added:"));
foreach (KeyValuePair<string, int> kvp in m_modules)
{
ns.Comments.Add(new CodeCommentStatement(string.Format("\t {0}", kvp.Key)));
}
cdp.GenerateCodeFromNamespace(ns, tw, null);
tw.Close();
}
}
}