initialized delegates in class diagram - c#

I use Visual Studio 2015, and I have created a class diagram to have an overview of my most-used classes and their members.
I have a delegate defined in a class named UserMessage:
public delegate void ProcessUserMessage(UserMessage message);
I use this delegate in an other class:
public UserMessage.ProcessUserMessage ProcessUserMessage;
So far no problems.
Because I hate testing the callback for null every time, I hook up a no-op event handler at initialization, as suggested here:
public UserMessage.ProcessUserMessage ProcessUserMessage = delegate { };
But when I do that, and re-open the class diagram, it fails to load, saying:
Code could not be found for one or more shapes in class diagram 'ClassDiagram1.cd'. Do you want to attempt to automatically repair the class diagram?
The auto-repair doesn't work of course ;-(
Even when I place this initiatlization in the class' constructor, instead of at the declaration, the same error appears.
I fail to understand what's wrong. Any clues?
Update:
I created a blank project with just the failing code:
public partial class MainWindow
{
public UserMessage.ProcessUserMessageDelegate ProcessUserMessage = delegate { };
}
public class UserMessage
{
public delegate void ProcessUserMessageDelegate(string foo);
}
The strange thing is that the class diagram for MainWindow loads fine, but for UserMessage it fails. But I am not changing anythign for UserMessage.
It loads OK if I change class MainWindow to:
public partial class MainWindow
{
public UserMessage.ProcessUserMessageDelegate ProcessUserMessage;
}

Found the solution...
The anonymous no-op delegate must conform to the delegate definition, so all I had to add was add the argument ((string foo) in this example):
public partial class MainWindow
{
public UserMessage.ProcessUserMessageDelegate ProcessUserMessage = delegate (string foo){ };
}
public class UserMessage
{
public delegate void ProcessUserMessageDelegate(string foo);
}

Related

C# Constructor on type not found when loading Design [duplicate]

I have a Visual Studio 2010 Windows Forms app which includes a Form base class that other classes will inherit. The base class' constructor takes a parameter that the child classes will pass to the base class.
Example:
public partial class BaseForm : Form
{
public BaseForm(int number)
{
InitializeComponent();
}
}
public partial class ChildForm : BaseForm
{
public ChildForm(int number)
: base(number)
{
InitializeComponent();
}
}
The problem that I'm running into is, when I attempt to open the ChildForm in VisualStudio's Design View mode, I receive the following error:
Constructor on type 'MyProject.BaseForm' not found.
Note: regardless of the error, the project compiles and runs fine.
I can avoid the error if I overload the constructor with one that does not contain any parameters.
Example: (This gets rid of the error)
public partial class BaseForm : Form
{
public BaseForm(int number)
{
InitializeComponent();
}
public BaseForm()
{
InitializeComponent();
}
}
public partial class ChildForm : BaseForm
{
public ChildForm(int number)
: base(number)
{
InitializeComponent();
}
}
My question is, how can I create a base class that does not include a parameterless constructor and avoid the Design View error?
That is completely impossible.
The form you see in the design view is an actual instance of your base class.
If there is not default constructor, the designer cannot create that instance.
You can mark the constructor with the [Obsolete("Designer only", true)], and make it throw an exception if called when not in the designer, to prevent other people from calling it.
You need to adjust your BaseForm output type, In the properties for the project, change the Output type from Windows Application to Class Library.
ref:
https://learn.microsoft.com/en-us/dotnet/framework/winforms/advanced/walkthrough-demonstrating-visual-inheritance

Call method in partial class

I'm using Visual Studios. I wrote a method in a form1.cs file in a partial class
private void TestMethod1()
{
}
I want to call this method in form2.designer.cs, in the same partial class. I tried this:
TestMethod1();
but I got the error method not found.
this is the form.cs
namespace classA
{
public partial class A : B
{....
private void TestMethod1()
{
}
}
}
this is the form.designer.cs
namespace classA
{
partial class A
{
private void InitializaCOmponent()
{
.....
}
(where I call my function)
TestMethod1();
}
}
If the situation is as you described, then the compiler should not generate the error message as it is valid code.
However, if you try to use the visual editor, and you insert the call in your code inside the InitializeComponent method you will get an error.
This is caused by the Form editor not being able to call functions that are defined within the class you are actually editing - it is a bit restrictive about what you can do within that scope.

How to get access to a subclass when the other class only knows the superclass?

I have a C# Windows Forms Application form1.cs with a Class Library (DLL) called class1.cs. Now on the UI side I do the following:
using System;
...
using System.Windows.Forms;
using ClassLibrary1;
namespace UI
{
public partial class Form1 : Form
{
MyLibraryClass mlc = null;
public Form1()
{
InitializeComponent();
mlc = new MyLibraryClass(this);
}
public void aMethod() {
Console.Write("Test");
}
}
}
In the Class Library I take the Form reference and want to call the method within, but I don't have access to it:
...
using System.Windows.Forms;
namespace ClassLibrary1
{
public class MyLibraryClass
{
private Form _form;
public MyLibraryClass(Form form)
{
this._form = form;
this._form.aMethod(); //Not working!
}
}
}
The reason as I understand it is that my ClassLibrary1 only knows Form but not Form1 and hence cannot call methods from Form1. The problem is, the UI knows the Class Library but not the other way around, since that would create a ring dependency as you certainly know. But how can I solve this problem?
Instead depeding of Form you can create an interface.
public interface IMyInterface {
void aMethod();
}
Form1 will implement the interface we created
public partial class Form1 : Form, IMyInterface
{
MyLibraryClass mlc = null;
public Form1()
{
InitializeComponent();
mlc = new MyLibraryClass(this);
}
public void aMethod() {
Console.Write("Test");
}
}
In MyLibraryClass now you will depend on the interface not the form. This way MyLibraryClass can use any form that respect the contract and we make sure that in MyClassLibrary will never be passed any intruder form.
public class MyLibraryClass
{
private IMyInterface _form;
public MyLibraryClass(IMyInterface form)
{
this._form = form;
this._form.aMethod(); // now is work :)
}
}
Notes:
The interface will be created in Class Library project (where MyClassLibrary is created).
I recommend you to take a look on SOLID principles.
Circular dependencies are something you will want to avoid whenever possible, but let's assume you still need this.
The easiest solution would be to put the MyLibraryClass and Form1 in the namespace, so you can replace the Form type parameter with a Form1. If you want to keep things nicely separate however, you will have to add a new type.
In you library you would have to add an interface that contains that method.
public interface IMyInterface
{
void aMethod();
}
If you then change the parameter to an IMyInterface instead, you have access to that method. If you need access to normal Form methods or the aMethod is always the same, you could opt for an abstract class that inherits from Form too.
Depend upon Abstractions. Do not depend upon concretions
public interface IMethod
{
void aMethod();
}
public partial class Form1 : Form,IMethod
public MyLibraryClass(IMethod form)
{
this._form = form;
this._form.aMethod();
}
If you can, you should enforce statically the Form1 class in the argument list:
public MyLibraryClass(Form1 form)
{
// ...
}
If you cannot (which is often the case when several assemblies are used) you should test and cast dynamically:
public MyLibraryClass(Form form)
{
if (form is Form1)
{
(form as Form1).aMethod();
}
}
BUT YOU REALLY SHOULD honor the DIP (Dependency inversion principle), instead: depend from abstractions. Implement an interface and depend from that instead of Form1.
But if you've had the issue in the first place, you probably haven't cleared out for yourself how dependencies are organized between assemblies or, worse, don't know exactly why some answers propose to use interfaces.
Read the link above to know more about why, because your problem really is not about HOW but WHY.

IntelliSense doesn't show partial class method

I have partial class User generated by LINQtoSQL as shortly following:
[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[User]")]
public partial class User : INotifyPropertyChanging, INotifyPropertyChanged
{
private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
...
Then I created separate folder "Proxy" in my project and put there extra piece of User class:
namespace LINQtoSQL_sample.Proxy
{
public partial class User
{
public static string GetActivationUrl()
{
return Guid.NewGuid().ToString("N");
...
Issue happens when I try to invoke that extra static method from another part of same project. Let's say I have once more folder "SqlRepositoryImpl" and another one partial class there:
namespace LINQtoSQL_sample.SqlRepositoryImpl
{
public partial class SqlRepository
{
public bool CreateUser(User instance)
{
if (instance.ID == 0)
{
instance.added_date = DateTime.Now;
instance.activated_link = LINQtoSQL_sample.Proxy.User.GetActivationUrl();
...
As you can see I explicitly defined which part of User class I'm calling for because IntelliSense didn't suggest me my extra method.
Please, advise why such happens and where I'm wrong?
As you can see I explicitly defined which part of User class I'm calling for because IntelliSense didn't suggest me my extra method.
When you call a method from a class, there are no “parts” of the class anymore.
If you need to (and can) specify the full namespace of the class to invoke a method from it that means you actually have two different classes in two different namespaces. If the two partial declarations are in different namespaces, then you have actually declared two separate classes, not a single class from two parts.

Override Default Constructor of Partial Class with Another Partial Class

I don't think this is possible, but if is then I need it :)
I have a auto-generated proxy file from the wsdl.exe command line tool by Visual Studio 2008.
The proxy output is partial classes. I want to override the default constructor that is generated. I would rather not modify the code since it is auto-generated.
I tried making another partial class and redefining the default constructor, but that doesn't work. I then tried using the override and new keywords, but that doesn't work.
I know I could inherit from the partial class, but that would mean I'd have to change all of our source code to point to the new parent class. I would rather not have to do this.
Any ideas, work arounds, 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...
}
}
}
I had a similar problem, with my generated code being created by a DBML file (I'm using Linq-to-SQL classes).
In the generated class it calls a partial void called OnCreated() at the end of the constructor.
Long story short, if you want to keep the important constructor stuff the generated class does for you (which you probably should do), then in your partial class create the following:
partial void OnCreated()
{
// Do the extra stuff here;
}
This is not possible.
Partial classes are essentially parts of the same class; no method can be defined twice or overridden, and that includes the constructor.
You could call a method in the constructor, and only implement it in the other part file.
Hmmm,
I think one elegant solution 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 drawbacks (as everything):
It is not clear when exactly will be executed the constructor of the MyCustomization inner class during whole construction procedure of the AutogenCls class.
If there will be necessary to implement IDiposable interface for the MyCustomization class to correctly handle disposing of unmanaged resources of the MyCustomization class, I don't know (yet) how to trigger the MyCustomization.Dispose() method without touching the AutogenCls.cs file ... (but as I told 'yet' :)
But this approach offers great separation from auto-generated code - whole customization is separated in different src code file.
enjoy :)
Actually, this is now 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 are defining the partial class, but not actually define the method in that file. In the other file, you can then define the method. If you are building an assembly where the method is not defined, then the ORM will remove all calls to the function.
So in the case 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 in order to override the default constructor
partial void OtherCode()
{
//do whatever extra stuff you wanted.
}
It is somewhat limited, and in this particular case, where you have a generated file that you'd need to alter, it might not be the right solution, but for others who stumbled on this trying to override functionality in partial classes, this can be quite helpful.
The problem that the OP has got is that the web reference proxy doesn't generate any partial methods that you can use to intercept the constructor.
I ran into the same problem, and I can't just upgrade to WCF because the web service that I'm targetting doesn't support it.
I didn't want to manually amend the autogenerated code because it'll get flattened if anyone ever invokes the code generation.
I tackled the problem from a different angle. I knew my initialization needed doing before a request, it didn't really need to be done at construction time, so I just overrode the GetWebRequest method like so.
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 nice solution because it doesn't involve hacking the auto generated code, and it fits the OP's exact use case of performing initialization login for a SoapHttpClientProtocol auto generated proxy.
You can't do this. I suggest using a partial method which you can then create a definition for. Something like:
public partial class MyClass{
public MyClass(){
... normal construction goes here ...
AfterCreated();
}
public partial void OnCreated();
}
The rest should be pretty self explanatory.
EDIT:
I would also like to point out that you should be defining an interface for this service, which you can then program to, so you don't have to have references to the actual implementation. If you did this then you'd have a few other options.
I am thinking you might be able to do this with PostSharp, and it looks like someone has done just what you want for methods in generated partial classes. I don't know if this will readily translate to the ability to write a method and have its body replace the constructor as I haven't given it a shot yet but it seems worth a shot.
Edit: this is along the same lines and also looks interesting.
Sometimes you don't have access or it's not allowed to change the default constructor, for this reason you cannot have the default constructor to call any methods.
In this case you can create another constructor with a 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 just pass dummy parameter like this:
SomeClass objSomeClass = new SomeClass(0);
This is in my opinion a design flaw in the language. They should have allowed multiple implementations of one partial method, that would have provided a nice solution.
In an even nicer way the constructor (also a method) can then also be simply be marked partial and multiple constructors with the same signature would run when creating an object.
The most simple solution is probably to add one partial 'constructor' method per extra 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 the partial classes to be agnostic 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 really they should just add some more language constructs to work with partial classes.
For a Web service proxy generated by Visual Studio, you cannot add your own constructor in the partial class (well you can, but it does not get called). Instead, you can use the [OnDeserialized] attribute (or [OnDeserializing]) to hook in your own code at the point where the web proxy class is instantiated.
using System.Runtime.Serialization;
partial class MyWebService
{
[OnDeserialized]
public void OnDeserialized(StreamingContext context)
{
// your code here
}
}
I'm not quite addressing the OP, but if you happen to be generating classes with the EntityFramework Reverse POCO Generator, there's a partial method called in the constructor which is handy for initializing things you're adding via partial classes on your own...
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; }
}
A bit late to the game, but this is indeed possible. Kind of.
I recently performed the trick below in a code generator of mine, and the result is satisfying. Yes, a dummy argument is required, but it will not cause any major concerns. For consistency, you may want to apply some rules:
Rules
Manually created constructor must be protected.
Generated constructor must be public, with the same arguments as the protected one plus an extra optional dummy argument.
The generated constructor calls the original constructor with all the supplied arguments.
This works for regular construction as well as reflection:
var s1 = new MyWebService();
var s2 = (MyWebService?)Activator.CreateInstance(
typeof(MyWebService),
BindingFlags.CreateInstance | BindingFlags.Public);
And for IoC, it should also work (verified in DryIoc). The container resolves the injected arguments, skipping the optional ones:
var service = container.Resolve<MyWebService>();
Sample code
// <auto-generated />
public partial class MyWebService
{
public MyWebService(object? dummyArgument = default)
: this()
{
// Auto-generated constructor
}
}
// Manually created
public partial class MyWebService
{
protected MyWebService()
{
}
}
The above works for any number of constructor arguments. As for the dummy arguments, we could invent a special type (maybe an enum) further restricting possible abuse of this extra argument.
Nothing that I can think of. The "best" way I can come up with is to add a ctor with a dummy parameter and use that:
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);

Categories

Resources