private void CollectMethods(Type type) { foreach (MethodInfo m in type.GetMethods()) { MethodComparator cmp = new MethodComparator(m); if (!mServiceMethods.Contains(cmp) && !mClientMethods.Contains(cmp) && !mNeutralMethods.Contains(cmp)) { // még nem detektált metódus OperationContractAttribute ocAnnotation = TypeHelper.GetAttribute <OperationContractAttribute>(m); if (ocAnnotation == null) { if (mWellKnownObjectMode == WellKnownObjectModeEnum.PerSession && typeof(IDisposable).IsAssignableFrom(type) && m.Name.Equals("Dispose")) { // perSession módban IDisposable-t nem dolgozunk fel, mert már implementálva van a ProxyBase-ben } else if (!m.IsSpecialName) { mNeutralMethods.Add(cmp); // a contract-ban nem vesz részt, de az interface-en valahol rajta van } } else if (ocAnnotation.Direction.Equals(OperationDirectionEnum.ServerSide)) { mServiceMethods.Add(cmp); } else { mClientMethods.Add(cmp); } } } foreach (PropertyInfo pi in type.GetProperties()) { PropertyComparator pc = new PropertyComparator(pi); if (!mNeutralProperties.Contains(pc)) { mNeutralProperties.Add(pc); } } foreach (EventInfo ei in type.GetEvents()) { mNeutralEvents.Add(new EventComparator(ei)); } if (type.GetInterfaces().Length > 0) { foreach (Type cls in type.GetInterfaces()) { CollectMethods(cls); } } }
/// <summary> /// Writes the abstract methods. /// </summary> /// <param name="methods">The methods.</param> /// <param name="stream">The stream.</param> public static void WriteAbstractMethods(IList <MethodComparator> methods, Stream stream) { if (methods == null) { ThrowHelper.ThrowArgumentNullException("methods"); } if (stream == null) { ThrowHelper.ThrowArgumentNullException("stream"); } IEnumerator <MethodComparator> iterator = methods.GetEnumerator(); while (iterator.MoveNext()) { MethodComparator mc = iterator.Current; Write(stream, NEW_LINE_BYTES); Write(stream, CODE_PUBLIC_METHOD); Write(stream, CODE_ABSTRACT_METHOD); if (mc.Method.ReturnType.Equals(typeof(void))) { Write(stream, VOID); } else { Write(stream, mc.Method.ReturnType.FullName); } Write(stream, SPACE); Write(stream, mc.Method.Name); Write(stream, BRACKET_LEFT); if (mc.Method.GetParameters().Length > 0) { for (int i = 0; i < mc.Method.GetParameters().Length; i++) { if (i > 0) { Write(stream, ", "); } Write(stream, mc.Method.GetParameters()[i].ParameterType.FullName); Write(stream, String.Format(" _p{0}", i)); } } Write(stream, BRACKET_RIGHT); Write(stream, SEMICOLON); Write(stream, NEW_LINE_BYTES); } }
public void Generate(string outputDir) { if (outputDir == null) { ThrowHelper.ThrowArgumentNullException("outputDir"); } if (!mIsCollected) { // reset fields mServiceMethods.Clear(); mClientMethods.Clear(); mNeutralMethods.Clear(); mNeutralProperties.Clear(); mNeutralEvents.Clear(); // collect methods CollectMethods(ContractType); mIsCollected = true; } FileStream fs = null; try { TypeDescriptor descriptor = new TypeDescriptor(ContractType); { DirectoryInfo outDir = new DirectoryInfo(outputDir); if (!outDir.Exists) { outDir.Create(); } } // generate service class(es) bool writeOverride = false; if (mWellKnownObjectMode == WellKnownObjectModeEnum.PerSession && mClientMethods.Count > 0) { // write abstract class FileInfo abstractFile = new FileInfo(Path.Combine(outputDir, String.Format("{0}.cs", descriptor.TypeNameServiceAbstract))); using (fs = new FileStream(abstractFile.FullName, FileMode.Create, FileAccess.Write, FileShare.Read)) { GeneratorBase.WriteAbstractProxyClassHeader(ContractType, true, fs); GeneratorBase.WriteEvents(mNeutralEvents, fs); GeneratorBase.WriteProxyContructor(false, descriptor.TypeNameServiceAbstract, fs); GeneratorBase.WriteAbstractProperties(mNeutralProperties, fs); GeneratorBase.WriteAbstractMethods(mServiceMethods, fs); GeneratorBase.WriteAbstractMethods(mNeutralMethods, fs); IEnumerator <MethodComparator> iterator = mClientMethods.GetEnumerator(); while (iterator.MoveNext()) { MethodComparator mc = iterator.Current; ServiceSideGenerator.GenerateServiceMethod(ContractType, mc.Method, fs); } GeneratorBase.WriteEndClass(fs); } writeOverride = true; } { FileInfo implFile = new FileInfo(Path.Combine(outputDir, String.Format("{0}.cs", descriptor.TypeNameServiceImpl))); using (fs = new FileStream(implFile.FullName, FileMode.Create, FileAccess.Write, FileShare.Read)) { String baseType = string.Empty; if (mWellKnownObjectMode == WellKnownObjectModeEnum.PerSession) { if (mClientMethods.Count > 0) { baseType = descriptor.TypeFullNameServiceAbstract; } else { baseType = typeof(ProxyBase).FullName; } } GeneratorBase.WriteImplementationClassHeader(ContractType, baseType, true, fs); if (!writeOverride) { GeneratorBase.WriteEvents(mNeutralEvents, fs); } if (mWellKnownObjectMode == WellKnownObjectModeEnum.PerSession) { GeneratorBase.WriteProxyContructor(true, descriptor.TypeNameServiceImpl, fs); } else { GeneratorBase.WriteEmptyContructor(true, descriptor.TypeNameServiceImpl, fs); } GeneratorBase.WriteProperties(mNeutralProperties, writeOverride, fs); GeneratorBase.WriteMethods(mServiceMethods, writeOverride, fs); GeneratorBase.WriteMethods(mNeutralMethods, writeOverride, fs); GeneratorBase.WriteEndClass(fs); } } // generate client class(es) writeOverride = false; bool disposeDetected = typeof(IDisposable).IsAssignableFrom(ContractType) && mNeutralMethods.Count == 1; if ((mClientMethods.Count > 0 || mNeutralMethods.Count > 0) && !disposeDetected) { // write abstract class FileInfo abstractFile = new FileInfo(Path.Combine(outputDir, String.Format("{0}.cs", descriptor.TypeNameClientAbstract))); using (fs = new FileStream(abstractFile.FullName, FileMode.Create, FileAccess.Write, FileShare.Read)) { GeneratorBase.WriteAbstractProxyClassHeader(ContractType, false, fs); GeneratorBase.WriteEvents(mNeutralEvents, fs); GeneratorBase.WriteProxyContructor(false, descriptor.TypeNameClientAbstract, fs); GeneratorBase.WriteAbstractProperties(mNeutralProperties, fs); GeneratorBase.WriteAbstractMethods(mClientMethods, fs); GeneratorBase.WriteAbstractMethods(mNeutralMethods, fs); IEnumerator <MethodComparator> iterator = mServiceMethods.GetEnumerator(); while (iterator.MoveNext()) { MethodComparator mc = iterator.Current; ClientSideGenerator.GenerateServiceMethod(ContractType, mc.Method, fs); } GeneratorBase.WriteEndClass(fs); } writeOverride = true; } { FileInfo implFile = new FileInfo(Path.Combine(outputDir, String.Format("{0}.cs", descriptor.TypeNameClientImpl))); using (fs = new FileStream(implFile.FullName, FileMode.Create, FileAccess.Write, FileShare.Read)) { String baseType = typeof(ProxyBase).FullName; if ((mClientMethods.Count > 0 || mNeutralMethods.Count > 0) && !disposeDetected) { baseType = descriptor.TypeFullNameClientAbstract; } GeneratorBase.WriteImplementationClassHeader(ContractType, baseType, false, fs); if (!writeOverride) { GeneratorBase.WriteEvents(mNeutralEvents, fs); } GeneratorBase.WriteProxyContructor(true, descriptor.TypeNameClientImpl, fs); GeneratorBase.WriteProperties(mNeutralProperties, writeOverride, fs); GeneratorBase.WriteMethods(mClientMethods, writeOverride, fs); if (disposeDetected) { // ha az IDisposable interface implementálva van, akkor a dispose() metódust nem szabad generálni kliens oldalon, mert a ProxyBase-ben már benne van IEnumeratorSpecialized <MethodComparator> iterator = mNeutralMethods.GetEnumerator(); while (iterator.MoveNext()) { MethodComparator mc = iterator.Current; if (mc.Method.Name.Equals("Dispose") && mc.Method.GetParameters().Length == 0) { iterator.Remove(); break; } } } GeneratorBase.WriteMethods(mNeutralMethods, writeOverride, fs); if (!((mClientMethods.Count > 0 || mNeutralMethods.Count > 0) && !disposeDetected)) { IEnumerator <MethodComparator> iterator = mServiceMethods.GetEnumerator(); while (iterator.MoveNext()) { MethodComparator mc = iterator.Current; ClientSideGenerator.GenerateServiceMethod(ContractType, mc.Method, fs); } } GeneratorBase.WriteEndClass(fs); } } } catch (Exception ex) { throw new ProxyGenerationFailedException("Failed to generate proxy classes.", ex); } }
/// <summary> /// Writes the methods. /// </summary> /// <param name="methods">The methods.</param> /// <param name="writeOverride">if set to <c>true</c> [write override].</param> /// <param name="stream">The stream.</param> public static void WriteMethods(IList <MethodComparator> methods, bool writeOverride, Stream stream) { if (methods == null) { ThrowHelper.ThrowArgumentNullException("methods"); } if (stream == null) { ThrowHelper.ThrowArgumentNullException("stream"); } IEnumerator <MethodComparator> iterator = methods.GetEnumerator(); while (iterator.MoveNext()) { MethodComparator mc = iterator.Current; Write(stream, NEW_LINE_BYTES); Write(stream, CODE_PUBLIC_METHOD); if (writeOverride) { Write(stream, "override "); } if (mc.Method.ReturnType.Equals(typeof(void))) { Write(stream, VOID); } else { Write(stream, mc.Method.ReturnType.FullName); } Write(stream, SPACE); Write(stream, mc.Method.Name); Write(stream, BRACKET_LEFT); if (mc.Method.GetParameters().Length > 0) { for (int i = 0; i < mc.Method.GetParameters().Length; i++) { if (i > 0) { Write(stream, ", "); } Write(stream, mc.Method.GetParameters()[i].ParameterType.FullName); Write(stream, String.Format(" _p{0}", i)); } } Write(stream, BRACKET_RIGHT); Write(stream, NEW_LINE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, LEFT_CURLY_BRACE); Write(stream, NEW_LINE_BYTES); int index = 0; bool commentWrote = false; foreach (ParameterInfo cls in mc.Method.GetParameters()) { if (typeof(Stream).IsAssignableFrom(cls.ParameterType)) { if (!commentWrote) { // stream detected, write notice and code pattern Write(stream, COMMENT_STREAM_NOTICE); Write(stream, CODE_BEGIN_TRY_BLOCK); Write(stream, COMMENT_PATTERN); Write(stream, NEW_LINE_BYTES); Write(stream, CODE_TRY_FINALLY); commentWrote = true; } Write(stream, TAB_SPACE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, String.Format("if (_p{0} != null)", index)); Write(stream, NEW_LINE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, "{"); Write(stream, NEW_LINE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, String.Format("_p{0}.Dispose();", index)); Write(stream, NEW_LINE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, RIGHT_CURLY_BRACE); Write(stream, NEW_LINE_BYTES); } index++; } if (commentWrote) { Write(stream, TAB_SPACE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, RIGHT_CURLY_BRACE); Write(stream, NEW_LINE_BYTES); } Write(stream, CODE_NOT_IMPLEMENTED_EXCEPTION); Write(stream, TAB_SPACE_BYTES); Write(stream, TAB_SPACE_BYTES); Write(stream, RIGHT_CURLY_BRACE); Write(stream, NEW_LINE_BYTES); } }