Override the default constructor for a partial class with another incomplete class

I do not think it is possible, but if I need it :)

I have an automatically generated proxy file from the wsdl.exe command line tool using Visual Studio 2008.

Proxy output is partial classes. I want to override the default constructor. I would prefer not to change the code as it is auto-generated.

I tried to make another partial class and override the default constructor, but this will not work. Then I tried to use redefinition and new keywords, but this does not work.

I know that I could inherit from a partial class, but that would mean that I would have to change all of our source code to point to the new parent class. I would rather not do this.

Any ideas, work around or hacks?

//Auto-generated class namespace MyNamespace { public partial class MyWebService : System.Web.Services.Protocols.SoapHttpClientProtocol { public MyWebService() { string myString = "auto-generated constructor"; //other code... } } } //Manually created class in order to override the default constructor namespace MyNamespace { public partial class MyWebService : System.Web.Services.Protocols.SoapHttpClientProtocol { public override MyWebService() { //this doesn't work string myString = "overridden constructor"; //other code... } } } 
+52
override c # wsdl overriding web-services partial-classes
Oct 29 '08 at 18:02
source share
12 answers

It's impossible. Partial classes are essentially part of the same class; no method can be defined twice or overridden, and it includes a constructor.

You can call the method in the constructor and implement it only in another file.

+38
Oct 29 '08 at 18:08
source share

I had a similar span with the generated code created by the dbml file (I use the Linq-to-SQL classes).

In the generated class, it calls a partial void named OnCreated () at the end of the constructor.

In short, if you want to save important constructor material that the generated class will do for you (which you should probably do), then create the following in your partial class:

 partial void OnCreated() { // Do the extra stuff here; } 
+68
Jan 09 '10 at 1:24
source share

Mmm, I think one of the elegant solutions would be the following:

 //* AutogenCls.cs file //* Let say the file is auto-generated ==> it will be overridden each time when //* auto-generation will be triggered. //* //* Auto-generated class, let say via xsd.exe //* partial class AutogenCls { public AutogenCls(...) { } } //* AutogenCls_Cunstomization.cs file //* The file keeps customization code completely separated from //* auto-generated AutogenCls.cs file. //* partial class AutogenCls { //* The following line ensures execution at the construction time MyCustomization m_MyCustomizationInstance = new MyCustomization (); //* The following inner&private implementation class implements customization. class MyCustomization { MyCustomization () { //* IMPLEMENT HERE WHATEVER YOU WANT TO EXECUTE DURING CONSTRUCTION TIME } } } 

This approach has some disadvantages (like everyone else):

  • It is unclear exactly when the constructor of the inner class MyCustomization will be executed during the entire procedure of building the AutogenCls class.

  • If you need to implement the IDiposable interface for the MyCustomization class to correctly handle the unmanaged resources of the MyCustomization class, I don’t yet know how to call the MyCustomization.Dispose () method without touching the AutogenCls.cs ... file (but, as I said "more": )

But this approach provides an excellent separation from automatically generated code - the entire configuration is shared in another src code file.

enjoy :)

+13
Apr 02 '10 at 20:57 on
source share

Actually, now it is possible now that partial methods have been added. Here's the doc:

http://msdn.microsoft.com/en-us/library/wa80x488.aspx

Basically, the idea is that you can declare and call a method in one file, where you define a partial class, but do not define a method in this file. In another file you can define a method. If you build an assembly where the method is not defined, ORM will delete all function calls.

So, in the example above, it would look like this:

// Auto-generated class

 namespace MyNamespace { public partial class MyWebService : System.Web.Services.Protocols.SoapHttpClientProtocol { public MyWebService() { string myString = "auto-generated constructor"; OtherCode(); } } } partial void OtherCode(); 

// Manually created class to override the default constructor

 partial void OtherCode() { //do whatever extra stuff you wanted. } 

It is somewhat limited, and in this particular case, when you have a generated file that you need to modify, this may not be the right solution, but for others who stumbled upon this while trying to redefine functionality in partial classes, it could be quite useful.

+3
Sep 27 '11 at 15:52
source share

The problem OP got is that the web link proxy does not generate any partial methods that can be used to intercept the constructor.

I ran into the same problem and I can't just switch to WCF because the web service that I am targeting does not support.

I did not want to manually modify the auto-generated code, because it will be smoothed out if anyone ever calls code generation.

I solved the problem from a different angle. I knew that my initialization should be done before the request, in fact, it didn’t have to be done during construction, so I just redefined the GetWebRequest method.

 protected override WebRequest GetWebRequest(Uri uri) { //only perform the initialization once if (!hasBeenInitialized) { Initialize(); } return base.GetWebRequest(uri); } bool hasBeenInitialized = false; private void Initialize() { //do your initialization here... hasBeenInitialized = true; } 

This is a pleasant solution, because it is not related to hacking automatically generated code, and it corresponds to a specific use case of OP to initialize the input for the automatically created SoapHttpClientProtocol proxy server.

+3
Jun 17 '13 at 16:06 on
source share

You cannot do this. I suggest using a partial method, which you can then create to define. Something like:

 public partial class MyClass{ public MyClass(){ ... normal construction goes here ... AfterCreated(); } public partial void OnCreated(); } 

The rest should be pretty clear.

EDIT:

I would also like to point out that you must define an interface for this service that you can program, so you do not need to have references to the actual implementation. If you do, you will have a few more options.

+2
Oct 29 '08 at 18:10
source share

I think you can do it with PostSharp , and it looks like someone has done exactly what you need for the methods in the generated partial classes . I don’t know if it’s easy to translate into a way to write a method and replace it with a constructor, since I have not given it a shot yet, but it seems worth taking a picture.

Edit: this is in the same directions , and also looks interesting.

+2
Oct 29 '08 at 18:28
source share

This, in my opinion, is a design error in the language. They had to allow several implementations of one partial method, which would provide a good solution. Even better, a constructor (also a method) can also be simply marked partial, and when creating an object, several constructors with the same signature will be executed.

The simplest solution is probably to add one partial constructor method for an additional partial class:

 public partial class MyClass{ public MyClass(){ ... normal construction goes here ... OnCreated1(); OnCreated2(); ... } public partial void OnCreated1(); public partial void OnCreated2(); } 

If you want partial classes to be agnostics about each other, you can use reflection:

 // In MyClassMyAspect1.cs public partial class MyClass{ public void MyClass_MyAspect2(){ ... normal construction goes here ... } } // In MyClassMyAspect2.cs public partial class MyClass{ public void MyClass_MyAspect1(){ ... normal construction goes here ... } } // In MyClassConstructor.cs public partial class MyClass : IDisposable { public MyClass(){ GetType().GetMethods().Where(x => x.Name.StartsWith("MyClass")) .ForEach(x => x.Invoke(null)); } public void Dispose() { GetType().GetMethods().Where(x => x.Name.StartsWith("DisposeMyClass")) .ForEach(x => x.Invoke(null)); } } 

But in reality they should just add a few language constructs to work with partial classes.

+1
Dec 30 '10 at 11:54
source share

Sometimes you do not have access or are not allowed to change the default constructor, so you cannot have a default constructor to call any methods.

In this case, you can create another constructor with the dummy parameter and make this new constructor to call the default constructor using ": this ()"

 public SomeClass(int x) : this() { //Your extra initialization here } 

And when you create a new instance of this class, you simply pass the dummy parameter as follows:

 SomeClass objSomeClass = new SomeClass(0); 
+1
Feb 14 2018-12-12T00:
source share

For the Visual Studio generated web service proxy, you cannot add your own constructor to the partial class (well, you can, but it is not called). Instead, you can use the [OnDeserialized] (or [OnDeserializing]) attribute to connect your own code at the point where the web proxy is being created.

 using System.Runtime.Serialization; partial class MyWebService { [OnDeserialized] public void OnDeserialized(StreamingContext context) { // your code here } } 
0
Feb 22 2018-11-11T00:
source share

I don’t quite turn to the OP, but if you generate classes using the POCO EntityFramework inverse generator, a partial method is called in the constructor, which is convenient for initializing things that you add through partial classes yourself ..

Generated by tool:

  [System.CodeDom.Compiler.GeneratedCode("EF.Reverse.POCO.Generator", "2.37.3.0")] public partial class Library { public string City { get; set; } public Library() { InitializePartial(); } partial void InitializePartial(); } 

added by you:

  public partial class Library { List<Book> Books { get; set; } partial void InitializePartial() { Books = new List<Book>(); } } public class Book { public string Title { get; set; } } 
0
Sep 18 '19 at 19:16
source share

Nothing I can think of. The “best” way I can think of is to add ctor with the dummy file parameter and use it:

 public partial class MyWebService : System.Web.Services.Protocols.SoapHttpClientProtocol { public override MyWebService(int dummy) { string myString = "overridden constructor"; //other code... } } MyWebService mws = new MyWebService(0); 
-one
Oct 29 '08 at 18:07
source share



All Articles