What is the best way to design this class hierarchy? - c#

I have a database table which contains an ID column and a Name column. I am tasked with designing a program that accepts one of the IDs as an argument to Main().
Bold is edit 2
I need to use that ID which must exist in the database, to correspond to some code to run. Each row in the table corresponds to slightly different code, but a lot of them share a lot of code. I need a design that will minimize code duplication.
So far what I've developed is an abstract base class that has an abstract Int32 field ID to enforce derived classes having their corresponding ID in the database. That way I can reflect over the derived classes to find the one whose ID matches the Main() argument and instantiate that class. Then I just call the virtual methods from Main() which runs the most derived code that has been defined.
public abstract class Base {
public abstract Int32 Id { get; }
public void Foo() {
// Do something
}
}
public class Derived {
public override Int32 Id { get { return 42; } }
public void Foo() {
// Do something more specific
}
}
Does anyone have any better ideas how to achieve what I want? I like the idea of keeping the ID right in the class definition, but I'm open to changing that if it makes sense.
Thanks!
EDIT:
One thing I don't like about this is that I have to reflect over each derived type and instantiate that type to check the ID. Does anyone have a better idea on how to do that?

Instead of using a property to define the ID of the class, use a custom attribute. That way, you don't have to instantiate the object to check what its ID is.
When your program runs, it can scan the assembly for all classes with that attribute tag, and find the one with the matching ID, instantiate that class, and then run it's Foo method. If you perform this kind of lookup multiple times per application run, you could instatiate all the classes with your custom attribute and then put them into a Dictionary to provide quick lookups by ID.
Your code might look something like this:
[AttributeUsage(AttributeTargets.Class)]
public class CommandAttribute {
public CommandAttribute(int id) {
ID = id;
}
public int ID { get; private set; }
}
public abstract class Command {
public abstract void Execute();
}
[Command(2)]
public class MyCommand : Command {
public override void Execute() {
//Do something useful
}
}
The other advantage of using a custom attribute is that you have to explicitly tag everything that is a candidate for being instantiated and executed by ID, rather than assuming than anything derived from your base class is a candidate. If you are sharing code between the classes, you might want to make a common base class for them that derives from your base class, but should not be instantiated or executed on its own.
One thing I don't understand is, what is the point of the "Name" field if the class you want to run is identified by the ID? If you can decide what the name of each ID is, then you could use the name field as the fully qualified type name of the class you want to execute, which then avoid having to scan through all the types in your assembly (or application domain, depending upon the scope of your search). That setup is a bit more prone to typos, however.

It sounds like you need to implement a factory pattern.
I would define an interface:
public interface IWidget
{
void Foo();
}
Then the base class:
public abstract class WidgetBase : IWidget
{
public void Foo()
{
this.Bar()
}
protected virtual void Bar()
{
// Base implementation
}
}
The factory:
public static WidgetFactory
{
public static IWidget Create(int id)
{
// Get class name from id, probably use the name in your database.
// Get Type from class name
// Get constructor for Type
// Create instance using constructor and return it.
}
}
A derived class:
public class DerivedWidget : WidgetBase
{
protected override void Bar()
{
// call base implementation
base.Bar();
// derived implementation
}
}
In your main:
public void Main(int id)
{
var widget = WidgetBase.Create(id);
widget.Foo();
}

I like #Xint0's idea of using a Factory for this kind of task, but I thought I'd still contribute another answer.
A better way to implement your original design would be to pass the ID to the base constructor as follows:
public abstract class Base {
public Int32 Id { get; private set; }
protected Base(Int32 id) {
this.Id = id;
}
public void Foo() {
// Do something
}
}
public class Derived : Base {
public Derived : base(42) {}
public void Foo() {
// Do something more specific
}
}

Related

Access to generic instance property

How can I access to the Id property of the instance? I have the following code:
public void InsertOrUpdate(Book book)
{
if (book.Id == default(int)) {
And I want to make it generic now:
public class TheRepository<T> : IRepository<T> where T : class
{
public void InsertOrUpdate(T instance)
{
if (instance.Id == default(int))//How can I access Id here
{
context.Set<T>().Add(instance);
I searched for similar posts and I think I should write something like instance.GetType().GetProperty("Id").GetValue() but I don't know how exactly?
You could do a hack like this. Define an interface with only one property of type int called Id:
interface IHaveId
{
public int Id { get; set; }
}
Then state that you entity implements the interface:
public class Book : IHaveId
Last state that the type used in your generic Repository class should implement this interface.
public class TheRepository<T> : IRepository<T> where T : class, IHaveId
{
public void InsertOrUpdate(T instance)
{
if (instance.Id == default(int))
{
context.Set<T>().Add(instance);
}
}
}
Doing so you avoid the use of reflection, which is very expensive in general terms. Furthermore, your code now is more clear.
Currently, the compiler knows nothing of T except that it's a class. This means that it can never know that it has an Id property, because there's nothing stopping you from creating an instance of TheRepository<string> - which doesn't have an Id property, of course.
The code snippet you mention in your answer, using reflection, is not a good way to do it. What happens if, as I mentioned, you create a repository of strings? This code will necessarily fail, because string doesn't have the Id property.
What you need to do in this case is make sure that class Book, along with any other entities you need to persist in the repository, implement a base class that includes ID:
public abstract class DataObject
{
public int Id {get;set;}
}
public class Book : DataObject
{}
Now, you can restrict your repository to classes that inherit DataObject:
public class TheRepository<T> : IRepository<T> where T : DataObject
Now, the compiler is assured that any instance of T, regardless of what T is, always inherits DataObject, and thus has an Id property.

Parametrized Abstract Factory / Factory Method / other creation patterns

I want to have some factory (doesn't matter if Abstract Factory pattern or Factory Method - looks like the second is specific form of the first one. In my case only one object should be created). The thing is that although created products are similar, they depends on some arguments.
How to prepare this architecture in compliance with design patterns?
Current approach below
public abstract class Product {}
public class MyProduct : Product
{
public bool Abc { get; set; }
}
public class YourProduct : Product {}
public abstract class ProductFactory
{
//in some cases parameter not in use
public abstract Product Create(HelpData additionalData);
}
public class MyProductFactory : ProductFactory
{
public override Product Create(HelpData additionalData)
{
return new MyProduct {Abc = additionalData.SomethingImportantForMyProduct};
}
}
public class YourProductFactory : ProductFactory
{
//unused parameter
public override Product Create(HelpData additionalData)
{
return new YourProduct();
}
}
public class HelpData
{
public bool SomethingImportantForMyProduct { get; set; }
}
EDIT
I see it's not clear so will repeat.
Usually I'm not using patterns just because of using them. But this problem seems not to be border case. Looks rather quite frequent. Going further I believe there's design pattern suitable to this, but I'm not sure which one. For now looks like abstract factory is not right choice.
Don't use design-patterns because you're using design-patterns. Always have in mind when to use one and when not. In your circumstances at least the abstract factory-pattern is wrong, as it assumes all factories to work with the same parameters. So if you have different parameters you surely need different factories.
However there's no way for the abstract factory to guess how to get an instance of a HelpData in some case but not in the other, so either pass it to every abstract factory or completely omit this further abstraction and stay with two independent factories:
public abstract class Product {}
public class MyProduct : Product
{
public bool Abc { get; set; }
}
public class YourProduct : Product {}
public class MyProductFactory
{
public Product Create(HelpData additionalData)
{
return new MyProduct {Abc = additionalData.SomethingImportantForMyProduct};
}
}
public class YourProductFactory
{
//unused parameter
public Product Create()
{
return new YourProduct();
}
}
public class HelpData
{
public bool SomethingImportantForMyProduct { get; set; }
}
Exposing a parameter only used within one factory to all factories isn't a good idea.
Besides this just imagine you don't have factories but any other classes that have a Create-method, where one needs a parameter, but the other one does not. Why should those two classes derive from the same base-class (in your case the abstract factory), when the don't have any common members? There's apparently no reason for this, so don't overcomplicate things just for the sake of using a pattern which doesn't fit.
Depending on where and how you retrieve additional data you could inject that data to the factory which will use it to construct the object:
public abstract class ProductFactory
{
public abstract Product Create();
}
public class MyProductFactory : ProductFactory
{
private HelpData additionalData;
public MyProductFactory(HelpData additionalData)
{
this.additionalData = additionalData;
}
public override Product Create()
{
return new MyProduct {Abc = additionalData.SomethingImportantForMyProduct};
}
}
public class YourProductFactory : ProductFactory
{
public override Product Create()
{
return new YourProduct();
}
}
Instead of passing HelpData to constructor of a factory you could inject a service that knows how to retrieve HelpData specific to the object being created. You could pass some other parameter to Create method if it is used for both factories.
I have also googled a bit and found good answer that explains why not https://stackoverflow.com/a/6241219/2138959. Passing a dictionary or a type that has property of dictionary type is also and option but in such approaches client has too much knowledge of a type it want to be created to use abstract factory.

Covariance with derived classes in C#

I have the following code (ready to paste into linqpad). Basically there is a base 'model' class with a 'treemembermodel' class deriving from it.
class MemberModel
{
public List<Member> Team = new List<Member>();
public void IncreaseAge()
{
// Would like this to modify the Treemember
Team[0].Age++;
}
}
class TreeMemberModel : MemberModel
{
public new List<TreeMember> Team = new List<TreeMember>();
public void UpdateName(string newName)
{
}
}
Same for a Member class with a 'TreeMember' deriving from it.
public class Member
{
public string Name;
public int Age;
}
public class TreeMember: Member
{
public string ParentName;
}
The idea is that the base member model stores a list of normal members, while the 'tree' model (and member) classes ensure a 'tree' structure by maintaining integrity between parent and subordinate fields.
This all seemed a good idea (the below example is stylised) - I figured any 'common' methods applying to both object types (eg 'increaseage' below) would modify the treeMember in the TreeModel when called from that model. However, calling 'increaseage' in my main method instead tries to access the 'Team' collection from the base 'MemberModel' instead, which of course doesn't exist.
void Main()
{
TreeMemberModel t = new TreeMemberModel();
t.Team.Add(new TreeMember() { Name = "original", Age = 10 });
// Call method within derived class
t.UpdateName("changed");
Console.WriteLine (t.Team[0].Name);
// Call method which drops down to base class method, and would like it to modify the TreeMemberModel's Team collection, not MemberModel's.
t.IncreaseAge();
Console.WriteLine (t.Team[0].Age);
}
I figure this is a covariance issue, and have tried a few things around making classes generic and so forth. Can I configure this so it drops back to the base class's methods while manipulating the elements of the TreeModel collection?
You should try following:
class MemberModel<TMember> where TMember : Member
{
public List<TMember> Team = new List<TMember>();
public void IncreaseAge()
{
// Would like this to modify the Treemember
Team[0].Age++;
}
}
class TreeMemberModel : MemberModel<TreeMember>
{
public void UpdateName(string newName)
{
}
}

Specify generic type as argument param without knowing T

I'm approaching a problem while still having some ignorance regarding Generics and their proper declarations / uses. I get the premiss, but some of the ins-n-outs of generics still elude me.
Given the following code (does not compile and contains code-smell):
public interface IUIConcern<out T> where T : IUIConcernExtension
{
string Name { get; }
Func<T> Extend();
}
public class UIConcern
{
public static void Register<T>(string concernName, IUIConcern<T> uiConcern) where T : IUIConcernExtension
{
Concerns.Add(uiConcern);
}
public static List<IUIConcern<T>> Concerns{
get {
// Logic...
}
set {
// Logic...
}
}
}
... I have a few questions:
Why do I have to specify this part public static void Register<T>(string concernName, IUIConcern<T> uiConcern) where T : IUIConcernExtension
with a constraint when I have already constrained the T in the declaration public interface IUIConcern<out T> where T : IUIConcernExtension
How can I have a property that holds a List<> of my IUIConcern<T> without knowing T other than knowing it will be derived from IUIConcernExtension?
Again, I realize this doesn't compile and is not correct, just looking to see how I can hold a list of generic items that may have many different type of IUIConcern<> elements.
Thank you!
You need to have a base interface, for instance:
public interface IUIConcern
{
string Name { get; }
}
public interface IUIConcern<out T> : IUIConcern where T : IUIConcernExtension
{
Func<T> Extern();
}
How you would define Concerns and Register would depend on how you treat T. Alternatively if you only deal with instances where you know T, you could use a Dictionary<Type, List<IUIConcern>> to hold anything, or potentially drop the base interface and just store using object depending on what you need in your controller code.
The problem is not located at the interface, but the problem is because of your generic implementation using static methods and properties.
The answer from Guvante was correct when saying that you need to define the IUIConcernExtension, but that is of course very logical, so im assuming you have just omitted that part since it does not matter for the issue you are facing.
The problem in the code is that you have created a class that has static methods and procedures, with the generic definition not laying at class level, but at methods level, because of this, the property that has and the Method cannot assume you are always with the same type!!
Lets say you call call :
Register<string>("something", UIConcern<string>)
but before that you have already called:
Register<Type>("something", UIConcern<Type>)
How could the compiler allows you to that?! So the answer is to define the generic type at class level, with this all properties and methods will be of same .
Also you need to use a private member for your list, since you doing everything static, the correct code should be:
interface IUIConcernExtension
{
string Name { get; }
}
public interface IUIConcern<out T> where T : IUIConcernExtension
{
Func<T> Extend();
}
public class UIConcern<T> where T : IUIConcernExtension
{
private static List<IUIConcern<T>> _Concerns = new List<IUIConcern<T>>();
public static void Register(string concernName, IUIConcern<T> uiConcern)
{
Concerns.Add(uiConcern);
}
public static List<IUIConcern<T>> Concerns
{
get { return _Concerns; }
set { _Concerns = value; }
}
}

Associate data with concrete subclasses from a base abstract type

I've stumbled upon the need to do this a few times recently with some lower level framework type stuff and I'd like to see if there is a better/cleaner way to accomplish this, i.e. if I'm missing something obvious or clever, like the time I discovered [ThreadStatic] to replace dictionary lookups against thread IDs for associating data with Threads.
I have a base abstract class, lets call it Entity. Every Entity needs to perform a set of initialization actions in the constructor that depends on the actual concrete class being instantiated. Is there a way I can accomplish this without doing a dictionary lookup and calling this.GetType()?
Here is some code similar to what I have now:
public abstract class Entity
{
private static Dictionary<Type, Action<EntityData>> _initActions = new Dictionary<Type, Action<EntityData>>();
private EntityData _data = new EntityData();
protected Entity()
{
_initActions[this.GetType()].Invoke(_data);
}
}
public class Employee : Entity
{
public string Name { get; set; }
}
public class Manager : Employee
{
public List<Employee> Subordinates { get; set; }
}
The Employee constructor and Manager constructor need to initialize their _data fields differently as they are different types. The _initActions collection gets initialized in another method prior to any instances being new'd up, which I don't think has any significance on this discussion.
I want usage of the class to remain as simple as possible for the user of the framework, so I can't use strange hacks like requiring users to override an Init method in each concrete type in some peculiar or unintuitive way.
Generics almost work, in the sense that I could do something like Entity<TEntity> to get a TEntity specific static field to store the init method if I didn't have any inheritance, but inheritance needs to be supported so I would need a dictionary of all init methods for the subclasses of TEntity anyway.
This code runs in some pretty low level database engine type scenarios in tight loops with 1m iterations, so getting rid of the dictionary lookup does provide some significant speedups in certain situations (tested by replacing with a hacky Init override implementation).
Any ideas?
EDIT:
I want to make a few things clear. The entity engine automatically sets up _initAction to do what it needs to to initialize its _data container. The "user" of the library knows nothing about this process and doesn't need to. All I was inquiring about is a way to avoid a dictionary lookup to get type-specific runtime information from a base class, but that may not be possible.
Yes, this is micro-optimization, but we have tested this with real queries and gotten 15-20% query time reductions on some queries that need to instantiate large datasets.
The faster code looked like this:
public class Employee : Entity
{
private static EntityInitializer _initMethod = Entity.GetInitMethod(typeof(Employee));
public string Name { get; set; }
public Employee()
{
_initMethod.Invoke(this);
}
}
This way, the dictionary lookup is done once for the Employee type. It's not horrible, but it requires a) boilerplate in every single class, which I don't like and b) slightly error prone as you have to match up the type parameter with the current class otherwise funky things happen, kind of like when you type in the wrong owner class name for a dependency property in WPF. Kinda sometimes works, but then wierd bugs pop up and its hard to trace back.
What it comes down to is this: is there was a better way to attach arbitrary runtime data to a Type besides using a Dictionary, considering that all these types that will have this data attached to them all implement a common base class?
Could you not just create a ctor that you pass the type to?
protected Entity(Type type)
{
_initActions[type].Invoke(_data);
}
}
public class Employee : Entity
{
private static Type mytype = typeof(Employee);
public string Name { get; set; }
public Employee(): base(mytype)
{ }
}
The lookup is causing performance issues?
Dictionary lookup is 0(1) and few milliseconds.
A program can only have so many classes.
Entity still needs to create the object, create a new EntityData, and run Invoke.
In addition to initialization of the classes that implement Entity.
Why does the type of the sub class effect the way an encapsulated class should be populated?
This seems like a violation of some OO principles to me.
If there is some specialized behaviour for a subclass, then
public abstract class Entity
{
private readonly EntityData data = InitializeData(new EntityData());
protected abstract void InitializeData(EntityData data);
}
seems like a better definition for the base class. The specilased action can be defined in the sub class,
Public class Employee : Entity
{
protected override void InitializeData(EntityData data)
{
// Employee specific implementation here ...
}
}
This requires no Dictionary, lookup or even a switch statement. No static state is required. It means the sub class related code has to be in the sub class but, that is a good thing, that is OO.
If its necessary to preserve more of what you have your could do somthing like,
public abstract class Entity
{
private readonly EntityData data;
protected Entity(Action<EntityData> initializeData)
{
this.data = initializeData(new EntityData());
}
}
public class Employee : Entity
{
public Employee : base(SomeStaticAction)
{
}
}
I really feel like you're overthinking this. Why not just have Entity have an abstract get-only property that needs to be overridden?
public abstract class Entity
{
private static Dictionary<Type, Action<EntityData>> _initActions =
new Dictionary<Type, Action<EntityData>>();
protected abstract EntityData _data { get; }
protected Entity()
{
_initActions[this.GetType()].Invoke(_data);
}
}
public class Employee : Entity
{
public string Name { get; set; }
protected overrides EntityData _data {
get { return new EntityData("Employee Stuff"); }
}
}
public class Manager : Employee
{
public List<Employee> Subordinates { get; set; }
protected overrides EntityData _data {
get { return new EntityData("Manager Stuff"); }
}
}
Alternatively, just have two Init methods.
public abstract class Entity
{
private static Dictionary<Type, Action<EntityData>> _initActions =
new Dictionary<Type, Action<EntityData>>();
private void InitalizeBase() { /* do shared construction */ }
protected abstract void Initalize();
protected Entity()
{
InitalizeBase();
Initalize();
}
}
public class Employee : Entity
{
public string Name { get; set; }
protected overrides Initalize()
{
// Do child stuff
}
}

Categories

Resources