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
}
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)
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.
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);}
}
}
In some locations of my program I need access to the concrete implementation of an object (Test) and in other locations I only need a read-only interface (ITest). This is to prevent an user from assuming that all properties are set and modifiable
For example if the user calls TestFactory.Search the returned collection will prevent them from modifying the property A and using CollectionB (it is not set inside the function). I would like to be able to use object initializers and keep the properties names the same. I have the following solution:
public interface IReadOnly
{
int Id{ get; }
string Name{ get; }
}
public class ClassA : IReadOnly
{
int Id{ get; internal set; }
string Name{ get; set; }
}
public interface ITest
{
int Id{ get; }
IReadOnly A { get; }
}
public class Test : ITest
{
private ClassA classA = new ClassA();
int Id{ get; internal set; }
IReadOnly ITest.A{ get{ return classA; } }
public ClassA A
{
get
{
return classA;
}
set
{
classA = value;
}
}
public IEnumerable<string> CollectionB {get;set;}
}
public static class TestFactory
{
IEnumerable<ITest> Search(){ /**/ }
Test Read(){ /**/ };
}
Is there a better way to solve this problem and is the abusing the concept of explicit interface implementation?
I would have your Test class implement both interfaces, IReadOnly and ITest. When you want to restrict setter access, cast to IReadOnly, otherwise, use ITest or the concrete Test.
Maybe create an abstract class instead and then subclass the full access and read only behavior?
I am looking at the LCOM metric as shown here,
http://www.ndepend.com/Metrics.aspx
So we are saying a few things,
1) A class is utterly cohesive if all its methods use all its instance fields
2) Both static and instance methods are counted, it includes also constructors, properties getters/setters, events add/remove methods
If I look at a class such as this,
public class Assessment
{
public int StartMetres { get; set; }
public int EndMetres { get; set; }
public decimal? NumericResponse { get; set; }
public string FreeResponse { get; set; }
public string Responsetype { get; set; }
public string ItemResponseDescription { get; set; }
public string StartText { get; set; }
public decimal? SummaryWeight { get; set; }
}
It gets a bad score of 0.94 because each getter and setter doesn't access 'all of the other instance fields'.
It is calculated like this,
accessAverage - methodCount / 1 - methodCount
(2 - 17) / (1 - 17) = 0.94 (rounded)
I am not understanding this metric, why should it include getters and setters? A getter and setter will always only access one single instance field.
This demonstrates that every software metric is flawed if you blindly take it to its extreme.
You know an "incohesive" class when you see one. For example:
class HedgeHog_And_AfricanCountry
{
private HedgeHog _hedgeHog;
private Nation _africanNation;
public ulong NumberOfQuills { get { return _hedgeHog.NumberOfQuills; } }
public int CountOfAntsEatenToday { get { return _hedgeHog.AntsEatenToday.Count(); } }
public decimal GrossDomesticProduct { get { return _africanNation.GDP; } }
public ulong Population { get { return _africanNation.Population; } }
}
This is obviously an incohesive class, because it contains two pieces of data that don't need to be with one another.
But while it's obvious to us that this class is incohesive, how can you get a software program to determine incohesion? How would it tell that the above class is incohesive, but this isn't?
class Customer
{
public string FullName { get; set; }
public Address PostalAddress { get; set; }
}
The metric they came up with certainly detects incohesion, but also comes up with false positives.
What if you decided this metric was important? You could create a "CustomerData" class containing just fields, and a "Customer" class that exposes the data fields as properties.
// This has no methods or getters, so gets a good cohesion value.
class CustomerData
{
public string FullName;
public Address PostalAddress;
}
// All of the getters and methods are on the same object
class Customer
{
private CustomerData _customerData;
public string FullName { get { return _customerData.FullName; } }
// etc
}
But if I'm playing this game, I can apply it to the incohesive example as well:
class Hedgehog_And_AfricanCountry_Data
{
public Hedgehog _hedgehog;
public AfricanNation _africanNation;
}
class Hedgehog_And_AfricanCountry
{
private Hedgehog_And_AfricanCountry_Data _hedgehogAndAfricanCountryData;
// etc;
}
Really, I think it's best to understand what cohesion is, and why it's a worthwhile goal, but also understand that a software tool can not properly measure it.