Factory Model in C# - c#

I have a bunch of MDI child nodes that are all created in the same way and to reduce redundant code I'd like to be able to call a method, pass it a string (name of child node), have it create the node and add it to the parent.
I can do all the stuff except create the class from a string of a class name, how can I do this?

I'm currently using this in one of my applications to new up a class
public static IMobileAdapter CreateAdapter(Type AdapterType)
{
return (IMobileAdapter)System.Activator.CreateInstance(AdapterType);
}
It's returning an instance of a class that implements IMobileAdapter, but you could use it equally easily with a string:
public static IMyClassInterface CreateClass(string MyClassType)
{
return (IMyClassInterface)System.Activator.CreateInstance(Type.GetType(MyClassType));
}
Call it using code similar to the following:
IMyClassInterface myInst = CreateClass("MyNamespace.MyClass, MyAssembly");
Of course, the class it creates must implement the interface IMyClassInterface in this case, but with a class factory, you'd likely have all your classes implementing the same interface anyway.
Edit:
In reference to your comment, for the purpose of this discussion, think of the term "assembly" as the set of files within your vb/cs project. I'm assuming that you're doing this all within a single project [assembly] and not spreading over multiple projects.
In your case as your classes will be extending the Form object, you would do something like this.
Form myInst = CreateClass("MyExtendedForm");
Or
Form myInst = CreateClass(Type.GetType("MyExtendedForm"));
Depending on whether you get the type within your CreateClass method or outside it. You would need to cast your instance to the correct type in order to access any custom members. Consider this:
class MyCustomForm : Form
{
public int myCustomField{ get; set; }
}
I've got a custom form that extends Form adding the myCustomField property. I want to instantiate this using Activator.CreateInstance():
public static Form CreateClass(string InstanceName)
{
return (Form)System.Activator.CreateInstance(Type.GetType(InstanceName));
}
I then call it using:
Form myInst = CreateClass("MyCustomForm");
So now I have my custom form stored in myInst. However, to access the custom property [myCustomField], you would need to cast your instance to the correct form:
int someVal = ((Type.GetType("MyCustomForm"))myInst).myCustomField;

Activator.CreateInstance(Type.GetType(typeName))

If you have a string which is the name of the class, then you should be able to get a Type object therefrom, by calling Type.GetType(string). From that type, you should be able to use reflection to generate an object.

Related

How to define a Class which is accessible in all classes in C#?

Am new to C#, but have a plenty of experience of VB.net, now my issue is that there are no modules in C# and i need to define a class which is accessible in all classes and i don't know how to do it.
For example I have a "classProject" and I need to make it accessible everywhere, so in vb.net , I will define it in module like below.
Module ModuleMain
Public tProject As New ClassProject
End Module
Now, I need to do same in C#.
Thanks in advance.
You can do this in your case:
namespace MyProject
{
public static class classProject
{
int myIntvar = 0;
string myStringvar = "test";
}
}
And you can use this static class in your other classes like:
public class Test
{
int intTest = classProject.myIntvar; //will be 0
string stringTest = classProject.myStringvar; // will be test
}
You can use the variables in the static class since a static variable shares the value of it among all instances of the class. When you create multiple instances of classProject class, the variables myIntvar and myStringvar are shared across all of other classes in your project. Thus, at any given point of time, there will be only one integer and one string value contained in the respective variable's.
It sounds like you're looking for a static class. You can reference the access modifiers here: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/access-modifiers
I think you need to extends your other classes to class father (ClassProject) And you can access to it with youur children classes.
//[access modifier] - [class] - [identifier]
public class Customer
{
// Fields, properties, methods and events go here...
}
see more

Having trouble with C# form passing

I'm currently trying to get into C#, after doing a ton of Java. I wanted to pass my GUI Form to another class, but I run into some trouble trying to access its containers etc. from there.
This is the autogenerated Form class:
namespace Wecker
{
public partial class WeckerDesign : Form
{
public WeckerDesign()
{
InitializeComponent();
new WeckerRun(this);
}
}
}
and this is the recieving class:
namespace Wecker
{
class WeckerRun
{
WeckerDesign wdesign = new WeckerDesign();
public WeckerRun(WeckerDesign wdesign)
{
this.wdesign = wdesign;
new DisplayClock(wdesign);
}
}
}
However, when I am trying to access the container "clockfield" from the recieving class, I can't find it. However, in the passing class, I can easily get there with this.clockpanel. ... and so on.
The recieving class won't even suggest me that. In Java, I would simply pass down my class as a whole with "this" in order to have the exact same reference in the other class, which I can treat as if I would do it in the original class where I got that object reference from.
How do I do this in C#?
How is your "clockpanel" field or property defined? It will need to be public to be accessible from outside the class.

Can't instantiate public instance of class from form code

I'm working on a windows forms application in c# and I can't figure out why I can't instantiate a class object from my form code. I have several classes, and from within all of those I can instantiate instances of the other classes publicly or just within methods with no problem.
However, when I try to instantiate one of those classes from my main form, it doesn't work.
It doesn't even recognize that I've just created an instance of the class.
The real kicker is that I can successfully instantiate a class from inside a method in my frmMain class:
private void Form_Load()
{
long deltaTime; int i; int page;
if (releaseMode)
{
modCanCable can = new modCanCable();
can.WaitWhileBusy();
}
All of the classes and form classes are under the same namespace too. Please let me know if you need to me to include any more information to help me find an answer!
You can only declare the global variable at the class level. Making use of that global variable must be done inside a property, method, or function.
For a global enumerator, declare it like you would any other variable
private EnumeratorClass VariableName;
Example (following naming conventions)
private MyEnum _myVariableName;
In C# all code has to be inside of a method. The line modCanCable can = new modCanCable(); declares a private field and uses a field initializer to initialize it to a new modCanCable instance. Any other refrence to the can field must be inside of a method body.
It must be done within a method or constructor. You cannot put it just in the class.
public partial class frmMain : Form
{
modCanCable cab = new modCanCable();
public frmMain()
{
cab.property = "asd";
}
}

C# Creating an object within a class

I'm making a map loading system that uses chunks so that the entire map data doesn't have to be loaded at once.
I have a "World" class, and within that class I'm creating an instance of a class called "ChunkManager".
I'm unsure if creating an instance inside another class is a good idea/considered a "normal" thing to do etc. I've not been able to find anything about this while searching the internet.
So my question is: Should I be creating an instance of a class within a class in the way I have, or will there be problems with doing it this way?
Here is my code, if it's relevant:
class World
{
public string WorldName { get; set; }
ChunkManager chunkManager = new ChunkManager();
public World(string worldName)
{
WorldName = worldName;
}
public void AddChunk(int X, int Y)
{
//Plus other validation code here that I didn't paste
chunkManager.AddChunk(X, Y);
}
}
And ChunkManager:
class ChunkManager
{
public int TotalGeneratedChunks { get; private set; }
private List<Chunk> ChunkList = new List<Chunk>();
public bool CheckIDExists(int IDToCheck)
{
foreach (Chunk i in ChunkList)
{
if (i.UniqueID == IDToCheck)
{
return true;
}
}
return false;
}
public void AddChunk(int X, int Y)
{
ChunkList.Add(new Chunk(TotalGeneratedChunks++, X, Y));
}
}
Your code is fine BUT if either class grows to be more complex and you want to be able to test them independently you should instead define an interface IChunkmanager and inject an instance of ChunkManager into World:
class World
{
public string WorldName { get; set; }
private readonly IChunkManager chunkManager;
public World(string worldName, IChunkManager chunkmanager)
{
this.chunkManager = chunkManager;
...
With this approach you can use a mocking framework to inject a mock IChunkManager and can test the World class independently.
In general classes should be loosely coupled. As soon as you new-up an instance of another class within a class you have tightly-bound them in a way that makes it hard to test them independently (or to reuse them in different situations).
It's perfectly fine to create an instance of a class inside another. chunkManager is what is known as a field and the syntax for initializing it inline along with its declaration is called an initializer. You can find more information on initializers and how they are different from initializing via the constructor in this blog series by Eric Lippert
Part 1
Part 2
It might some times be a better idea to initialize fields via the constructor though as this lets you use dependency injection (parameter injection to be precise) which can greatly improve the testability and modularity of your code. If you're interested in learning more about dependency injection I suggest purchasing and reading this book.
Standard practice is to set values inside the constructor because it allows for dependency injection and makes modifying the constructor to use an argument trivially easy.
If you are going to create a lot of World, i suggest creating an Abstract base that implements the ChunckManager.
That way you can leverage the use of base class, promote code reuse. You can also make your ChunkManager singleton since it only needs to be used by the base, and then use a method to actually instantiate the ChunkManager if you need specific properties from maps.
Use DI to pass the prop from child to base to instantiation of the ChunkManager
yes you can use one class type in another class its like one of filed on this class like when you use string a=new string() you use an object of class string its normal code

Class extending - best practice/best solution

First thing to note - I KNOW DELEGATION AND DECORATOR PATTERNS!
Second - I am using C# .NET 4.0, so if you come up with a solution that is specific for it, that's fine. But if solution will work for any OOP language and platform, that would be great.
And here the question goes...
I have a partial class (lets name it Class1), which I cannot modify. Thus, I can just extend it or/and inherit from it. This class provides a perfect data model for me, the only thing I need is to add some attributes to its properties (for validation, defining label text value in MVC etc - for now, I do not need answers like 'you can do what you need without attributes', that's not the matter of my question).
It is not a problem to use another class as a data model, so I can, say, create Class2 : Class1 and use Class2 as a model. Properties that need attributes would be defined as public new <type> <propertyname>. This will limit me to rewriting only the properties that need attributes, leaving all other untouched.
The smaller problem is that I do not what to redefine getters and setters for the properties, as all they gonna contain is return base.<propertyname> and base.<propertyname> = value, and if there are lots of such properties, this means lots of "stupid" coding. Is there a way to avoid this?
The bigger problem is that I have to parametrize my Class2 with Class1 instance and make something like class2.<propertyname> = class1.<propertyname> for each single property I have - too much of "stupid" coding. I can avoid it using reflection - find all properties with public getters and setters in Class1 and call prop.SetValue(child, prop.GetValue(parent, null), null); in the loop. This provides a generic function for simple cases, which is quite fine, as I mostly have simple models - lots of properties with public getters and setters without body and another logic. But I want more generic solution, and I do not like reflection. Any ideas?
Here goes the full code of the extension method that creates Class2 basing on Class1
public static Child ToExtendedChild<Parent, Child>(this Parent parent)
where Child : Parent, new()
{
Child child = new Child();
var props = typeof(Parent).GetProperties().Where(p => p.GetAccessors().Count() >= 2);
foreach (var prop in props)
{
prop.SetValue(child, prop.GetValue(parent, null), null);
}
return child;
}
(by the way, this method may not ideally implement my solution, so any corrections would also be appreciated)
Thanks in advance!
The smaller problem doesn't seem to be much of a problem. Maybe I'm misunderstanding the question, but assuming you're simply deriving a subclass, there should be no reason to redefine either the properties or their associated getters/setters.
The bigger problem might be resolved using something a little simpler. Using reflection for a lot of your object initialization seems a little expensive. If you're dealing with a class that is primarily a big bag or properties, maybe you should as if you need access to all of those properties in any given situation. You mention MVC and validation, is the entire model being used in the controller method you're validation is taking place in? If not, why not look at using a viewmodel that only exposes those pieces you need in that method?
Your reflection initializer is interesting, but if you're going to be doing a lot of this then you might consider investing a little time with Automapper. Otherwise maybe consider moving away from a generic solution to something that just tackles the problem at hand, i.e. mapping properties from an instance of an object to another instance of a derived object. Maybe you can create a copy constructor in the parent class and use that in your derived class?
public class Foo {
public string PropOne { get; set; }
public string PropTwo { get; set; }
public Foo(string propOne, string propTwo) {
PropOne = propOne;
PropTwo = propTwo;
}
public Foo(Foo foo) {
PropOne = foo.PropOne;
PropTwo = foo.PropTwo;
}
}
public class Pho : Foo {
// if you have additional properties then handle them here
// and let the base class take care of the rest.
public string PropThree { get; set; }
public Pho(string propOne, string propTwo, string propThree)
: base(propOne, propTwo) {
PropThree = propThree;
}
public Pho(Pho pho) : base(pho) {
PropThree = pho.PropThree;
}
// otherwise you can just rely on a copy constructor
// to handle the initialization.
public Pho(Foo foo) : base(foo) {}
}
I assume the partial class is generated code, it makes the most sense given your scenario.
I know of one way to do this, but depending on how the attribute gets crawled, it may not work.
// Generated Code
public partial Class1
{
public string Foo { get { ... } }
}
// Your Code
public interface IClass1
{
[MyAttribute]
public string Foo { get; }
}
public partial Class1 : IClass1
{
}
If someone were to look at attributes by using GetCustomAttributes with inheritance, then I think they would get this attribute.
As an aside, whenever I see generated code that doesn't have virtual properties it makes me cry a little bit inside.
To address your bigger question, why don't you just make Class2 a wrapper for Class1. Instead of copying all of the properties you can just give Class2 an instance of Class1 in the constructor, store it locally and make all of your properties pass-throughs. It means some hand coding, but if you're building a Class2 by hand anyway and want to decorate it with a bunch of attributes, well, you're hand coding Class2 anyway.

Categories