After having to refactor the inheritance chain in my current project for the third time I googled "Inheritance sucks" and found that the problem I'm having is not uncommon and composition is a recommended alternative solution.
I understand how you can use composition to add behavior in form of functions, but I'm having problems to come up with ways to add properties by the same means.
Let's say I want to model tree nodes. Every node has at least two properties: name and description.
class Node {
public string Name { get; set; }
public string Description { get; set; }
}
Other more specific nodes would inherit those properties, like so:
class StructuredNode : Node {
public List<Node> Children { get; set; }
}
How could I achieve similar re-usability of the property code without relying on inheritance and the problems that come with it?
Is there a design pattern for this or do I have to use inheritance in such a case?
Thanks in advance!
Edit:
Examples for the position "composition over inheritance":
ScottLilly
Wikipedia
Codingdelight
Rather then depending on class , you should depend son abstraction (this also one part of making use of composition) so for you case you should do like this
public interface INode {
string Name { get; set; }
string Description { get; set; }
}
class Node : INode {
public string Name { get; set; }
public string Description { get; set; }
}
class StructuredNode : INode {
public string Name { get; set; }
public string Description { get; set; }
public List<INode> Children { get; set; }
}
or you can also do this
//this is something similar to decorator pattern.
class StructuredNode {
private readonly INode _node;
public StructureNode(INode node)
{
_node = node;//now you can reuse function of any class which implements INode
}
public List<INode> Children { get; set; }
}
you should do like this also later on
List<Node> nodes = List<Node>();
StructuredNode sNode = new StructuredNode();
sNode.Children = nodes;
this is possible as all is based on abstraction. and all implementation now make use of INode
or
other solution suggested you in comment is make use of Decorator pattern. If you just want to extend you class without modifying it.
How could I archive similar re-usability of the property code without relying on inheritance and the problems that come with it?
The alternative to using inheritance is either interfaces or composition. However, for properties specifically, you're a bit stuck.
Interfaces cannot contain a default implementation the same way that a base class can. So while you can enforce that your classes use the correct "composed property structure", you can't make reusable methods available without implementing them in every class that implements the interface (or can you? More after the break!)
Composition simply doesn't exist in C# in a way that you can add properties to a class on the fly (unless you are satisfied with a Dictionary<string,string>). There may be some contrived method to technically make it work, but it won't be a good approach.
Interfaces + extension methods.
Extension methods can be used here to replace the reusable logic that you'd find in an inherited base class.
There is one drawback to this: The properties that you wish to access inside the extension methods need to be part of the interface contract and publically accessible.
Other than this drawback, it ticks the box on every other requirement you have.
First, an inheritance-based example:
public class Property
{
public string Name { get; set; }
public string Value { get; set; }
}
public class PropertyComposedObject
{
public List<Property> Properties { get; set; }
public Property GetProperty(string name)
{
return this.Properties.SingleOrDefault(x => x.Name == name);
}
}
public class Person : PropertyComposedObject
{
}
If we were to use an interface instead, we would lose access to benefits such as a shared GetNode(string) method. You could add it as part of the interface, but each implementing class would then be responsible for implementing that method (leading you to copy/paste the same methods all over the place).
An interface example without extension methods:
public class Property
{
public string Name { get; set; }
public string Value { get; set; }
}
public interface IPropertyComposedObject
{
List<Property> Properties { get; set; }
Property GetProperty(string name);
}
public class Person : IPropertyComposedObject
{
public List<Property> Properties { get; set; }
public Property GetProperty(string name)
{
return this.Properties.SingleOrDefault(x => x.Name == name);
}
}
But extension methods allows us to define the reusable method once but still access it from every class that implements the interface:
public class Property
{
public string Name { get; set; }
public string Value { get; set; }
}
public interface IPropertyComposedObject
{
List<Property> Properties { get; set; }
}
public class Person : IPropertyComposedObject
{
public List<Property> Properties { get; set; }
}
public static class IPropertyComposedObjectExtensions
{
public Property GetProperty(this IPropertyComposedObject obj, string name)
{
return obj.Properties.SingleOrDefault(x => x.Name == name);
}
}
My attempt to minimize code duplication:
interface INodeProperties
{
string Name { get; set; }
string Description { get; set; }
}
class NodeProperties : INodeProperties
{
public string Name { get; set; }
public string Description { get; set; }
}
interface INode
{
INodeProperties NodeProps { get; set; }
}
class Node : INode
{
public INodeProperties NodeProps { get; set; } = new NodeProperties();
}
interface IStructuredNode
{
List<Node> Children { get; set; }
}
class StructuredNode: INode, IStructuredNode
{
public INodeProperties NodeProps { get; set; } = new NodeProperties();
public List<Node> Children { get; set; }
}
Downside: One more "hop" to get to the actual Properties ... :(
Have an INode interface, which encapsulates common properties.
This way you should have auto properties, then avoid putting logic in properties' getter and setter, because you can not reuse this logic.
Then repeating auto property definitions is not important and does not affect reusability.
If you need property change notification, it is better to use interceptor libraries such as postsharp.
Related
I am having a problem. Lets see an example:
you got this interface which would be implemented by Employee.cs and Owener.cs:
public interface IEmployee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Location { get; set; }
}
public class Employee: IEmployee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Location { get; set; }
}
public class Owner: IEmployee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Location { get; set; }
public string Status{ get; set; } <--- //problem string
}
Now when we are using Dependency Injection and it returns the object of employee or manager, thats where i run into problem.
public class EmployeeCheck{
private IEmployee empObj;
public EmployeeCheck(IEmployee _em)
{
empObj=_em
}
public void PrintCheck()
{
string str=_em.FirstName;
string str2=(Owner)_emp.Status <--- //problem...how do I access it?? It can't be accessed cause
//IEMployee doesn't have status field!
}
So basically if I use IEmployee as the interface , I can't access fields in new the Owner class, and if I do put them in interface, then Employee class which doesn't need to implement it, will be forced to implement something it doesn't need! And I do need IEmployee due to DI injection or other design pattern
OK, I can't use abstract class...so lets discuss more about the IStatus solution...so you are talking about writing code like this:
public interface IStatus:IEmployee
{
public string Title { get; set; }
}
public class Owner: IEmployee, IStatus
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Location { get; set; }
public string Status{ get; set; } <--- //problem string
}
But how do I work it in Employee check class?
public class EmployeeCheck
{
private IEmployee empObj;
public EmployeeCheck(IEmployee _em, IStatus)
{
empObj=_em
}
}
The scenario that you're dealing with could be handled traditionally using IoC Containers like StructureMap or Unity by using something called Named Instances. These containers provide this kind of functionality out of the box.
The same can be achieved in .NET Core in multiple ways. One way is to use the extension method from IServiceCollection. The below snippet walks you through how this could be done in your scenario
// using Microsoft.Extensions.DependencyInjection
// Startup.cs - ConfigureServices()
services.AddTransient(serviceProvider =>
{
Func<string, IMyClass> func = key =>
{
switch (key)
{
case "MyClass":
return serviceProvider.GetService<MyClass>();
case "MyClass1":
return serviceProvider.GetService<MyClass2>();
default:
throw new KeyNotFoundException();
}
};
return func;
});
//Register your services here as usual
services.AddTransient<IMyClass, MyClass>();
services.AddTransient<IMyClass, MyClass2>();
You are essentially creating a factory here that is going to give out the dependency of the type that you need based on the key. The following snippet of code shows how this can be done within your controller.
// ctor of your controller
public MyController(Func<string, IMyClass> injector)
{
// key here could be 'MyClass' or 'MyClass2'
IMyClass service = injector("<key>");
}
Below is the structure of sample classes I have considered for the above sample
// implementation 1
public class MyClass : IMyClass
{
}
// implementation 2
public class MyClass2 : IMyClass
{
}
// interface
public interface IMyClass
{
}
There are also other ways to handle this. You can take a look at this answer for other approaches.
It depends on how you use or why you have to use dependency injection. I think that in these cases according to your example it is not so good to use it, since it is giving you complexity in something simple.
If you are going to perform an action with the Status value, you could segregate the interface by generating a new one. Like this.
public interface IStatus { string Status { get; set; } } and then you implement this interface just in Owner and in your constructor EmployeeCheck you inject IStatus.
But if it is not necessary why not IEmployee you do it as an abstract class.
public abstract class Employee
{
public string Name { get; set; }
public string LastName { get; set; }
public string Location { get; set; }
}
public class Owner : Employee
{
public string Status { get; set; }
}
public class EmployeeCheck
{
public EmployeeCheck(Employee employee)
{
var owner = employee as Owner;
var statuts= owner.Status;
}
}
The first question you need to consider is: what is EmployeeCheck supposed to do when it is instantiated with an Employee (say) since it seems to require Status to print a check?
The whole idea behind interfaces is that they provide a contract for the operations that can be performed with an object. In this case, you are trying to do something (use Status) that is not specified in the contract so the type system is making it a little bit harder (forcing you to cast).
An option (as suggested by #Diegorincon) which avoids casting, is to create another interface (something like IHasStatus) which implements IEmployee and then change the type in EmployeeCheck (CheckPrinter maybe clearer?) to IEmployeeWithStatus.
interface IEmployee
{
string FirstName { get; }
string LastName { get; }
}
interface IEmployeeWithStatus:IEmployee
{
string Status { get; }
}
public class Owner : IEmployeeWithStatus
{
public string FirstName { get; }
public string LastName { get; }
public string Status { get; }
}
class EmployeeCheck
{
private readonly IEmployeeWithStatus _employeeWithStatus;
public EmployeeCheck(IEmployeeWithStatus employeeWithStatus)
{
_employeeWithStatus = employeeWithStatus;
}
void PrintCheck()
{
// no casting needed
Console.Write($"{_employeeWithStatus.FirstName} {_employeeWithStatus.LastName} {_employeeWithStatus.Status}");
}
}
If you are stuck using the signatures in your example, one option for writing the code is to write a switch statement using the type pattern:
switch (employee)
{
case Owner owner:
{
// you can use owner.Status here
Console.WriteLine(owner.Status);
}
break;
case Employee employee:
{
// hmm.., now what?!
}
break;
}
It's cleaner than having to cast all over the place but at the end of the day, it's just pushing the same problem around.
(In the Object Oriented paradigm, this situation comes up all the time where you have a object in hand with a more general type (something like Animal) but you find yourself wanting to do operations based on its specific type (something like Dog). Switching on type as the code above does is usually considered a code smell. With more details, I might be able to offer some other ideas)
I'm reading user input from different types of CSV files having a few common and a few different attributes. I have created a base class TestCaseData and derived classes as below:
public abstract class TestCaseData
{
public abstract string ID { get; set; }
public abstract string Name{ get; set; }
}
public class DerivedClassOne :TestCaseData
{
public override string ID { get; set; }
public override string Name{ get; set; }
pubic string DerivedOneProperty{ get; set; }
}
public class DerivedClassTwo :TestCaseData
{
public override string ID { get; set; }
public override string Name{ get; set; }
pubic string DerivedTwoProperty{ get; set; }
}
I am reading the CSV file and creating a list of derived classes and assigning to list of base class as below
List<TestCaseData> lstTestCaseData = MethodCallToReturnListOf_DerivedOneClassFromCSV();
As now I have lstTestCaseData I have to validate the user inputs also where I am unable to find a way to write a single method to validate user input of type DerivedOneProperty or DerivedTwoProperty as they have their own properties. Anyone can help me here?
I have method signature something like that
public string ValidateCompleteFile(List<TestCaseData> TestCaseInputList, out bool IsInputValid)
You could instead put an abstract validation method on the TestCaseData class and then let each class that inherits this class implement it how they need to.
public abstract class TestCaseData
{
public abstract string ID { get; set; }
public abstract string Name{ get; set; }
public abstract bool Validate();
}
And then call this method for each entry in the TestCaseInputList collection.
The answer regarding an abstract method is the best solution if you're committed to the code pattern you originally conceived of (i.e. calling a validation method on each object). But perhaps it would be better to validate each field in its setter:
public abstract class TestCaseData
{
private string id, name;
public abstract string ID { get; set; }
public abstract string Name{ get; set; }
}
public class DerivedClassOne : TestCaseData
{
public override string ID
{
get { return id; }
set
{
if ( ... ) throw new ArgumentException();
...
id = value;
}
}
...
}
This way an exception is thrown as soon as an invalid value is encountered. Imagine if you created a million of these objects before checking if each one was valid, only to find that the very first one was invalid. This solution avoids a situation like that by proactively validating as the properties are set.
i have two data classes which hold only data members(no functions). One is CallTask the other is SmsTask. These two classes have some common properties like ID, Tel. I put these common properties in a seperate interface class and i use this interface class in my project whenever appropriate.
Now i added a WCFService to my project to share data between clients and server. Consider the following class design:
public interface IGsmTask : IComparable
{
string TaskID { get; set; }
string SessionID { get; set; }
string Tel { get; set; }
}
class CallTask : IGsmTask
{
#region IGsmTask Members
public string TaskID { get; set; }
public string SessionID { get; set; }
public string Tel { get; set; }
#endregion
}
class SmsTask : IGsmTask
{
#region IGsmTask Members
public string TaskID { get; set; }
public string SessionID { get; set; }
public string Tel { get; set; }
#endregion
public string SmsText { get; set; }
}
in this design, i want to host CallTask, SmsTask, and IGsmTask to the clients to use these in service methots like the following;
[OperationContract]
public void AddTask(IGsmTask task)
{
}
i tried to mark [DataContract] on IGsmTask but it gives me complition error. Isnt there any methot that i can use interfaces as DataContracts? Or how should i use KnownAttributes types in this synerio?
Thanks.
As far as I know using interfaces as datacontracts is not possible. You may use a base class and add knowntype attributes on the otherhand.
Fer: Everything is Possible with the right design.
If the issue is:
a class is a data contract
&&
1 or more of its properties must be an interface...
public interface ICustomInterface
{
int Property1 {get;set}
}
[DataContract]
public class MyClass
{
[DataMember(Name="_myInterface")]
public ICustomInterface MyInterface {get;set;}
}
The issue is that when the de-serialization occurs --
There is no way to turn the data into a class that implements ICustomInterface.
The Solution is to create a concrete class that does Implement the interface, and cast the getter/setter of the public property (that is of type interface) into a private property of the concrete class.
public class CustomInterfaceImplementor: ICustomInterface
{
public int Property1 {get;set;}
}
[DataContract]
public class MyClass
{
[DataMember(Name="_myInterface")]
private CustomInterfaceImplementor _MyInterface;
public ICustomInterface MyInterface
{
get {return (_MyInterface as ICustomInterface);}
set {_MyInterface = (value as CustomInterfaceImplementor);}
}
}
I have the following interface declarations:
interface IOrder<T> where T: IOrderItem
{
IList<T> Items { get; set; }
}
interface IOrderItem
{
IOrder<IOrderItem> Parent { get; set; } // What do I put here?
}
I want the items in the list to have a reference to the header object, so it can use the ID and other fields from the header.
In my concrete classes, it complains that I don't implement "Parent" properly.
class StoreOrder : IOrder<StoreOrderItem>
{
public IList<StoreOrderItem> Items { get; set; }
}
class StoreOrderItem : IOrderItem
{
public StoreOrder Parent { get; set; } // This doesn't satisfy the interface
}
I tried setting up IOrderItem as IOrderItem<T> and passing in the Parent type, but that lead to circular reference since the Header class requries the Item class type... I got confused.
Any advice on how to implement this properly?
If you define your interfaces like so:
interface IOrder<T> where T : IOrderItem<T>
{
IList<T> Items { get; set; }
}
interface IOrderItem<T> where T : IOrderItem<T>
{
IOrder<T> Parent { get; set; }
}
You can then implement them like this to get the functionality that you expect:
class StoreOrder : IOrder<StoreOrderItem>
{
public IList<StoreOrderItem> Items { get; set; }
}
class StoreOrderItem: IOrderItem<StoreOrderItem>
{
public IOrder<StoreOrderItem> Parent { get; set; }
}
class StoreOrder : IOrder<StoreOrderItem>
{
public int Id { get; set; }
}
class StoreOrderItem : IOrderItem
{
public IOrder<IOrderItem> Parent { get; set; } // This doesn't satisfy the interface
}
You may not specialize - IOrder<IOrderItem> is more general than StoreOrder
Here's a solution for changing the interfaces:
interface IOrder<TOrder, TOrderItem>
where TOrderItem : IOrderItem<TOrder>
{
IList<TOrderItem> Items { get; set; }
}
interface IOrderItem<TOrder>
{
TOrder Parent { get; set; }
}
Making changes to StoreOrder and StoreOrderItem to support the interface changes AND adding a couple properties to each for a later test:
class StoreOrder: IOrder<StoreOrder, StoreOrderItem>
{
public DateTime Date { get; set; }
public IList<StoreOrderItem> Items { get; set; }
}
class StoreOrderItem : IOrderItem<StoreOrder>
{
public string ItemName { get; set; }
public decimal ItemPrice { get; set; }
public StoreOrder Parent { get; set; }
}
...and now creating StoreOrder and StoreOrderItem instances, and putting them through their paces:
void Main()
{
var so = new StoreOrder { Date = DateTime.Now };
var item = new StoreOrderItem {
Parent = so,
ItemName = "Hand soap",
ItemPrice = 2.50m };
so.Items = new [] { item };
Console.WriteLine(item.Parent.Date);
Console.WriteLine(so.Items.First().ItemName);
}
...when run, printed:
3/16/2012 10:43:55 AM
Hand soap
Another option is to scrap the above and take this solution and alter it by adding the Parent property with the desired type and using explicit interface implementation to avoid casting at the call-sites, making for a StoreOrderItem implementation something like this:
class StoreOrderItem : IOrderItem
{
public string ItemName { get; set; }
public decimal ItemPrice { get; set; }
public StoreOrder Parent { get; set; } // note: original implementation
IOrder<IOrderItem> IOrderItem.Parent { // explicit interface implementation
get { return (IOrder<IOrderItem>)this.Parent; }
set { this.Parent = (StoreOrder)value; }
}
}
My favorite of the above is the first proposal above with the two-generic parameters to IOrder and the unconstrained generic-parameter on IOrderItem. A previous version I had posted and have now edited had both interfaces each with the same two generic types each with the same constraints. I felt like this was going a bit overboard so I pared it back to the above implementation. Although there is a complete lack of constraints on TOrder type parameter to IOrderItem - attempts to fudge other types in its place (e.g., object) resulted in compile errors. Using TOrder instead of just calling it T provides a hint about the expected type in the absence of the type constraint. That will be my final edit - I feel it is the most succinct of my attempts; if you are curious I can provide the former implementation that had the double-generic-constrained-types on the interfaces, but this is at least my preferred this solution. cheers!
Declaration to satisfy the interfaces:
class StoreOrder : IOrder<StoreOrderItem>
{
// interface members
public IList<StoreOrderItem> Items { get; set; }
// own members
public int Id { get; set; }
}
class StoreOrderItem : IOrderItem
{
public IOrder<IOrderItem> Parent { get; set; }
}
To access custom members you will have to cast:
class StoreOrderItem : IOrderItem
{
void Test()
{
int id = ((StoreOrder)this.Parent).ID;
}
}
I have a set of interfaces which are used in close conjunction with particular mutable object.
Many users of the object only need the ability to read values from the object, and then only a few properties. To avoid namespace pollution (easier intellisense) and to get across the usage intent, I'd like to have a small base interface which only exposes a few "key" properties in a read-only fashion.
However, almost all implementations will support the full interface, which includes modifiability.
Unfortunately, I ran into a roadblock expressing that concept in C#:
interface IBasicProps {
public int Priority { get; }
public string Name {get;}
//... whatever
}
interface IBasicPropsWriteable:IBasicProps {
public int Priority { set; } //warning CS0108: [...] hides inherited member [...]
public string Name { set; }
//... whatever
}
I certainly wasn't intending to hide any members, so that aint good!
Of course, I can solve this using methods just fine, but what's the right choice? I'd like to keep the "core" interface as small as possible even if splitting the interfaces serves no purpose other than communicating intent. With split interfaces, it's just really obvious which methods aren't going to do any updating, and it makes writing code a bit clearer (not to mention also allows nice-n-simple static singleton stubs that suffice for quite a few simple cases).
I'd like to avoid any abstract classes and the like; they make reimplementation or quick single-purpose shims all that more complex and hard-to-grok.
So, ideas?
Method hiding in an interface isn't nearly as grungy; I'd go with something like:
interface IBasicProps {
int Priority { get; }
string Name {get;}
//... whatever
}
interface IBasicPropsWriteable:IBasicProps {
new int Priority { get; set; }
new string Name { get; set; }
//... whatever
}
class Foo : IBasicPropsWriteable {
public int Priority {get;set;}
public string Name {get;set;}
/* optional
int IBasicProps.Priority {get {return Priority;}}
string IBasicProps.Name {get {return Name;}}
*/
}
If your goal is to make it clearer when reading vs. writing is allowed, then I would use separate getter and setter methods rather than properties.
interface IBasicProps {
int GetPriority();
string GetName();
//... whatever
}
interface IBasicPropsWriteable:IBasicProps {
void SetPriority(int priority);
void SetName(string name);
//... whatever
}
One way could be to simply skip the inheritance of the interfaces. Make one read-only interface and one write-only, and implement as necessary:
interface IBasicPropsReadable {
int Priority { get; }
string Name { get; }
}
interface IBasicPropsWriteable {
int Priority { set; }
string Name { set; }
}
class SomeClassReadWrite : IBasicPropsReadable, IBasicPropsWriteable {
int Priority { get; set; }
string Name { get; set; }
}
class SomeClassReadOnly : IBasicPropsReadable {
int Priority { get; }
string Name { get; }
}
You could leave the interfaces unrelated and simply have your class implement both interfaces. After all the interfaces are simply defining the contract and the contracts don't need to be related. It seems like it just an optimization for you when coding to have the writeable one derive from the other, so you only have to specify one interface.
public interface IBasicProps
{
int Priority { get; }
string Name {get;}
//... whatever
}
public interface IBasicPropsWriteable
{
int Priority { get; set; }
string Name { get; set; }
//... whatever
}
public class Foo : IBasicProps, IBasicPropsWriteable
{
public int Priority { get; set; }
public string Name { get; set; }
// whatever
}
If you really needed the optimization, you could create another interface that derives from both and have your classes implement that.
public interface IBasicPropsAll : IBasicProps, IBasicPropsWriteable { }
public class Foo : IBasicPropsAll
{
public int Priority { get; set; }
public string Name { get; set; }
// whatever
}