I have a little utility class called ContainerQuery which consists of zero or more ContainerQueryClause objects. After the user has prepared the query (i.e. added some clauses), the interface for my framework needs to get an object that supports:
interface IContainerQuery
{
public IEnumerable<ContainerQueryClause> Clauses { get; }
}
What's the best implementation for IContainerQuery and why?
Option a)
class ContainerQuery
{
public IEnumerable<ContainerQueryClause> Clauses { get; set; }
}
Option b)
class ContainerQuery
{
public ContainerQuery()
{
Clauses = new List<ContainerQueryClause>();
}
public ICollection<ContainerQueryClause> Clauses { get; private set; }
}
Option c)
class ContainerQuery
{
public ContainerQuery(IEnumerable<ContainerQueryClause> clauses)
{
Clauses = clauses;
}
public IEnumerable<ContainerQueryClause> Clauses { get; private set; }
}
Option d)
A combination of the above approaches or a completely different approach.
Side note 1: although ContainerQuery currently looks like "it is an enumerable of clauses" I want to model it for the future's sake as "has an enumerable of clauses".
Q: Is there a general best pracitce / pattern to create properties of type IEnumerable<T>? If not, which approach fits which situations?
Side question: Would you create the interface IContainerQuery to have your internal framework use the immutable version only or would you forbear from doing so as "your internal code is not stupid enough to change the query later on"?
Some additional context: the user instantiates a new container query and wants to add some clauses. There is no funky fluent interface or things like that. After passing the finished query to my framework, my framework only wants to read all the clauses and is not allowed to make any changes to it (per interface description).
Start with the following implementation. Why? It provides minimum knowledge and possibilities to the caller.
you can use the class with the default constructor => no thinking needed
about what happens to the parameter
Clauses is always initialized => no need to check for null
Clauses is IEnumerable => minimum set of functionality, maximum flexibility for inner representation
If you can live with the implementation, you are done. If you think that a ContainerQuery without Clause doesn`t make sense, add it to the constructor so that the caller is forced to give a value. If you suggest that the caller need some methods from ICollection (adding/removing after construction of ContainerQuery) than use this interface. And so on ...
public class ContainerQuery : IContainerQuery
{
public ContainerQuery()
{
Clauses = new List<ContainerQueryClause>();
}
public IEnumerable<ContainerQueryClause> Clauses { get; private set; }
}
Related
I have a 'naïve' question.
With the following sample code:
public class ThisClass
{
public int ThisClassID { get; set; }
public string ThisValue { get; set;}
public ThisClass()
{
}
public ThisClass(int thisClassID)
{
using (MyContext dbContext = new MyContext())
{
this = dbContext.CaseNotes.Find(thisClassID);
}
}
}
And, of course, I get the error Cannot assign to 'this' because it is read-only
The only two ways of solving this that I know of are to have a static method, or to assign to each property separately.
Is there any way of creating a simple constructor that returns database entities into this?
UPDATE
Both answers below are correct but I can only accept one. There was some interesting discussion on the use of factories and repository patterns that were sadly deleted when a potential answer was deleted. Arguments were equally balanced both for and against with some pointing out the the Entity Framework itself is a factory that uses a repository pattern. The question itself had three upvotes and two downvotes.
The answer seems to be that there is no single answer.
You should take a look at AutoMapper, and your code could look as follows:
// Somewhere in your application/service initialization class and in some method...
Mapper.CreateMap<ThisClass, ThisClass>();
public class ThisClass
{
public int ThisClassID { get; set; }
public string ThisValue { get; set;}
public ThisClass()
{
}
public ThisClass(int thisClassID)
{
using (MyContext dbContext = new MyContext())
{
Mapper.Map(dbContext.CaseNotes.Find(thisClassID), this);
}
}
}
BTW it sounds like a bad idea. I wouldn't populate a domain object inside its own constructor.
This is a good responsibility for the repository.
Is there any way of creating a simple constructor that returns database entities into this?
In practice no. In theory you can make the type a struct. Then, the code should compile. You can assign to this in a struct.
Probably, you should not use a constructor at all. Create a factory method that simply returns the result from Find.
One unchangeable fact about constructors is that they create a fresh object every time. I don't think you want that here. You probably want to preserve the existing object instance and its identity.
I'm trying to make an app I'm designing more generic and implement the command pattern into it to use manager classes to invoke methods exposed by interfaces.
I have several classes with the GetItem() and GetList() methods in them, some are overloaded. They accept different parameters as I was trying to use dependency injection, and they return different types. Here are a couple of examples:
class DatastoreHelper
{
public Datastore GetItem(string DatastoreName)
{
// return new Datastore(); from somewhere
}
public Datastore GetItem(int DatastoreID)
{
// return new Datastore(); from somewhere
}
public List<Datastore> GetList()
{
// return List<Datastore>(); from somewhere
}
public List<Datastore> GetList(HostSystem myHostSystem)
{
// return List<Datastore>(); from somewhere
}
}
class HostSystemHelper
{
public HostSystem GetItem(int HostSystemID)
{
// return new HostSystem(); from somewhere
}
public List<HostSystem> GetList(string ClusterName)
{
//return new List<HostSystem>(); from somewhere
}
}
I'm trying to figure out if I could use a generic interface for these two methods, and a manager class which would effectively be the controller. Doing this would increase the reuse ability of my manager class.
interface IGetObjects
{
public object GetItem();
public object GetList();
}
class GetObjectsManager
{
private IGetObjects mGetObject;
public GetObjectsManager(IGetObjects GetObject)
{
this.mGetObject = GetObject;
}
public object GetItem()
{
return this.mGetObject.GetItem();
}
public object GetList()
{
return this.GetList();
}
}
I know I'd have to ditch passing in the parameters to the methods themselves and use class properties instead, but I'd lose the dependency injection. I know I'd have to cast the return objects at the calling code into what they're supposed to be. So my helper classes would then look like this:
class DatastoreHelper
{
public string DatastoreName { get; set; }
public string DatastoreID { get; set; }
public object GetItem()
{
// return new Datastore(); from somewhere
}
public List<object> GetList()
{
// return List<Datastore>(); from somewhere
}
}
class HostSystemHelper
{
public int HostSystemID { get; set; }
public string ClusterName {get; set;}
public object GetItem()
{
// return new HostSystem(); from somewhere
}
public List<object> GetList()
{
//return new List<HostSystem>(); from somewhere
}
}
But is the above a good idea or am I trying to fit a pattern in somewhere it doesn't belong?
EDIT: I've added some more overloaded methods to illustrate that my classes are complex and contain many methods, some overloaded many times according to different input params.
If I understand the concept correctly, a design like this is a really bad idea:
class DatastoreHelper
{
public string DatastoreName { get; set; }
public string DatastoreID { get; set; }
public object GetItem()
{
// return new Datastore(); from somewhere
}
public List<object> GetList()
{
// return List<Datastore>(); from somewhere
}
}
The reason is that getting results would now be a two-step process: first setting properties, then calling a method. This presents a whole array of problems:
Unintuitive (everyone is used to providing parameters as part of the method call)
Moves the parameter binding away from the call site (granted, this would probably mean "moves them to the previous LOC", but still)
It's no longer obvious which method uses which property values
Take an instance of this object and just add a few threads for instant fun
Suggestions:
Make both IGetObjects and GetObjectsManager generic so that you don't lose type safety. This loses you the ability to treat different managers polymorphically, but what is the point in that? Each manager will be in the end specialized for a specific type of object, and unless you know what that type is then you cannot really use the return value of the getter methods. So what do you stand to gain by being able to treat managers as "manager of unknown"?
Look into rewriting your GetX methods to accept an Expression<Func<T, bool>> instead of bare values. This way you can use lambda predicates which will make your code massively more flexible without really losing anything. For example:
helper.GetItem(i => i.DataStoreID == 42);
helper.GetList(i => i.DataStoreName.Contains("Foo"));
The first code samples look quite similar to the Repository Pattern. I think this is what are you trying to apply. The last sample is not good and Jon told you why. However, instead of reinventing the wheel, read a bit about the Repository (lots of questions about it on SO) because, if I understood correctly, this is what you really want.
About reuse, not many things and especially persistence interface are reusable. There is the Generic Repository Pattern (I consider it an anti-pattern) which tries to accomplish that but really, do all the application needs the same persistence interface?
As a general guideline, when you design an object, design it to fullfil the specific application needs, if it happens to be reused that's a bonus, but that's not a primary purpose of an object.
It is not a good idea. Based on these examples you would be better off with a generic interface for the varying return type and parameters of GetItem/GetList. Though honestly the prevalence of Managers, the use of something cas vague as GetItem in multiple places and trying to fit your solution into design patterns (rather than defining the solution in terms of the patterns) are huge code smells to me for the wider solution.
I have an interface named IDeviceId that I use in my domain. I also have several concrete classes that implement IDeviceId. Each concrete class contains the logic for a specific type of DeviceId. For example, I have DeviceMacId, which is simply a valid MAC address. Another concrete class is DeviceShortMacId, which takes the last 6 digits of a valid MAC address and combines it with a fixed 6-character prefix to create a valid MAC (several legacy apps use only the last 6 digits). I have a few other classes for expressing an ID, but the majority of them are all derivatives of the same data.
I'd like to be able to easily convert from any one of these classes to another. My first thought was to create a static class and do something like DeviceIdConverter.ToDeviceShortMacId(IDeviceId).
What's the best way be able to easily accept data in one form, and then convert it to another in a repeatable fashion (across multiple apps)?
I don't think there is a "best way" to do this, you're going to have to find a pattern that works for you and go with it.
Off the top of my head, based on the examples you presented I would do something like:
interface IDeviceId
{
// Other methods
IDeviceId ToDeviceShortMacId(IDeviceId);
IDeviceId ToDeviceMacId(IDeviceId);
// etc...
}
Then each of the classes would need to implement the conversion methods. Now if you plan on adding a lot of other implementation (concrete) classes later, then this could get pretty verbose. So what you might consider in that case is in each of the projects which creates a new implementation you also create extension methods like:
public static class MacDeviceIdExtensions
{
public static DeviceMacId ToDeviceMacId(this IDeviceId deviceId)
{
// Implement conversion
}
public static DeviceShortMacId ToDeviceMacId(this IDeviceId deviceId)
{
// Implement conversion
}
}
The extension methods approach is a lot more modular, but could also be a lot more code.
One possibility would be to implement your own casting:
public static explicit operator DeviceShortMacId(DeviceMacId deviceMacID)
{
return new DeviceShortMacId(deviceMacID.MacAddress);
}
public static explicit operator DeviceMacId(DeviceShortMacId deviceShortMacID)
{
return new DeviceMacId(deviceShortMacID.MacAddress);
}
That way you can do:
DeviceMacId newDeviceId = (DeviceShortMacId)deviceMacID
With this approach, if some conversions are not possible, you can handle that yourself and throw an InvalidCastException.
Call me old fashioned, but I kind of like the static method approach here. You'll have the conversion logic decoupled from your entities, with a descriptive method name to describe what each conversion does. You might also want to consider implementing them as extension methods.
Why don't you just create constructors on all your IDeviceID implementing classes that accept an IDeviceID object.
DeviceMacID macID = new DeviceMacID(...whatever you do normally...);
DeviceShortMacID shortMacID = new DeviceShortMacID((IDeviceID)macID);
Example code
public DeviceShortMacID : IDeviceID
{
private ID _ID;
public DeviceShortMacID() { }
public DeviceShortMacID(IDeviceID id)
{
if (id is DeviceshortMacID)
this._ID = id.GetID();
else
this._ID = this.ConvertFrom(id);
}
public ID ConvertFrom(IDeviceID oldID) { ... convert code ...}
public ID GetID() { return this_ID; }
}
public interface IDeviceID
{
public ID GetID();
public ID ConvertFrom(IDeviceID oldID);
}
public class ID { } // I don't know what you return so I'm making up this class
I have a library (no source), to an certain object of which, I need to add some properties.
What would be the a way to do it ? I'm aware I could extend the class and add properties to the child. As well I know there are NO Extension Properties in C# yet. What would you suggest ? Thank you !
The metadata of class could be something like :
public class ResultClass
{
public IList<Item> Results { get; set; }
public int TotalResults { get; set; }
}
and I want to add a :
String description;
to it. Thanks.
There are a couple strategies you could take. Inheritance is the most obvious one. You might also consider composition. Can you give us some more details about what the object is and what properties you need to add to it and why?
After seeing the expanded question:
Either strategy outlined above (composition or inheritance) will probably work for you. Personally, I prefer composition. I think it better insulates you from changes that might be made to the third party library. It also forces you to work through the public interface of the library class, which is preferable when you have no knowledge or control of the internals of a class.
Here is the most basic example of composition.
public CompositeClass
{
private ResultClass _resultClass = new ResultClass();
public IList<Item> Results
{
get { return _resultClass.Results; }
set { _resultClass.Results = value; }
}
public int TotalResults
{
get { return _resultClass.TotalResults; }
set { _resultClass.TotalResults = value; }
}
//
// New Property
//
public string Description { get; set; }
}
Why do you need to add properties? If this is for binding purposes then I would suggest creating a wrapper class or creating your own inherited type that can raise PropertyChanged events in response to various state changes in your third party types. Instead of telling us your proposed solution you should tell us the actual problem you are trying to solve. Also (as I can't vote to close/migrate), this is not really a valid discussion for this site.
I think you are mixing up Extension Methods with Extension Properties.
And the last ones do not exist in C#.
So you should extend the class or create an inheriting class.
I previously posted this, but I guess it was too verbose and irrelevant. My question is also like this. One poster in the second link said the answer (of why you can't do the code below) was a problem of design, specifically "bad use of inheritance". So I'd like to check this issue again with the experts at StackOverflow and see if this is really an issue of "bad inheritance" - but more importantly, how to fix the design.
Like the poster, I'm also confused about the Factory method and how I can apply it. It seems the factory method is for multiple concrete classes that have the exact same implementation as the abstract base class and do not add their own properties. But, as you will see below, my concrete classes build upon the abstract base class and add extra properties.
The Base Class We Build Upon:
public abstract class FlatScreenTV
{
public string Size { get; set; }
public string ScreenType { get; set; }
}
Extension Class Examples:
public class PhillipsFlatScreenTV : FlatScreenTV
{
// Specific to Phillips TVs. Controls the backlight intensity of the LCD screen.
public double BackLightIntensity { get; set; }
}
public class SamsungFlatScreenTV : FlatScreenTV
{
// Specific to Samsung TVs. Controls the time until the TV automatically turns off.
public int AutoShutdownTime { get; set; }
}
Let's say there are more extension classes for more brands of flat screen TVs. And then, let's say we stick them all into a generic List:
public static void Main()
{
List<FlatScreenTV> tvList = new List<FlatScreenTV>();
tvList.Add(new PhillipsFlatScreenTV());
tvList.Add(new SamsungFlatScreenTV());
tvList.Add(new SharpFlatScreenTV());
tvList.Add(new VizioFlatScreenTV());
FlatScreenTV tv = tvList[9]; // Randomly get one TV out of our huge list
}
The Problem:
I want to access the specific properties of whatever 'original' brand TV this variable belongs to. I know the brand because if I call tv.GetType(), it returns the correct 'original' type - not FlatScreenTV. But I need to be able to cast tv from FlatScreenTV back to its original type to be able to access the specific properties of each brand of flat-screen TVs.
Question #1: How can I dynamically cast that, properly - without makeshift hacks and huge if-else chains to brute-guess the 'original' type?
After browsing around similar design issues, most answers are: you can't. Some people say to look at the Factory Pattern, and others say to revise the design using interfaces, but I don't know how to use either to solve this problem.
Question #2: So, how should I design these classes so that I can access the original type's specific properties in the context above?
Question #3: Is this really bad inheritance?
Your design violates the "Liskov Substitution Principle". In other words, the code that deals with items from your list of FlatScreenTV shouldn't know or care what derived type is.
Say your code needs to create a custom remote control GUI. It might be enough to simply know the names and types of the properties of each TV to auto-generate the UI. In which case you could do something like this to expose the custom properties from the base class:
public abstract class FlatScreenTV
{
public FlatScreenTV()
{
CustomProperties = new Dictionary<string,object>();
}
public Dictionary<string,object> CustomProperties { get; private set; }
public string Size { get; set; }
public string ScreenType { get; set; }
}
public class PhillipsFlatScreenTV : FlatScreenTV
{
public PhillipsFlatScreenTV()
{
BackLightIntensity = 0;
}
// Specific to Phillips TVs. Controls the backlight intensity of the LCD screen.
public double BackLightIntensity
{
get { return (double)CustomProperties["BackLightIntensity"]; }
set { CustomProperties["BackLightIntensity"] = value; }
}
}
public class SamsungFlatScreenTV : FlatScreenTV
{
public SamsungFlatScreenTV()
{
AutoShutdownTime = 0;
}
// Specific to Samsung TVs. Controls the time until the TV automatically turns off.
public int AutoShutdownTime
{
get { return (int)CustomProperties["AutoShutdownTime"]; }
set { CustomProperties["AutoShutdownTime"] = value; }
}
}
If you really do need to be working directly with the derived types, then you should instead consider moving to a plugin based architecture. For example, you might have a factory method like this:
IRemoteControlGUI GetRemoteControlGUIFor(FlatScreenTV tv)
which would scan your plugins and find the one that knew how to build the UI for the particular type of FlatScreenTV you passed in. This means that for every new FlatScreenTV you add, you also need to create a plugin that knows how to make its remote control GUI.
Factory Pattern would be the best way to go
I can offer a partial answer:
Firstly read up on Liskov's Substitution Principle.
Secondly you are creating objects that inherit from FlatScreenTV, but apparently for no purpose as you want to refer to them by their SubType (SpecificTVType) and not their SuperType (FlatScreenTV) - This is bad use of Inheritance as it is NOT using inheritance lol.
If your code wants to access properties particular to a given type, then you really want this code encapsulated within that type. Otherwise everytime you add a new TV type, all the code that handles the TV list would need to be updated to reflect that.
So you should include a method on FlatScreenTV that does x, and override this in TV's as required.
So basically in your Main method above, instead of thinking I want to be dealing with TVTypeX, you should always refer to the basetype, and let inheritance and method overriding handle the specific behaviour for the subtype you are actually dealing with.
Code eg.
public abstract class FlatScreenTV
{
public virtual void SetOptimumDisplay()
{
//do nothing - base class has no implementation here
}
}
public class PhilipsWD20TV
{
public int BackLightIntensity {get;set;}
public override void SetOptimumDisplay()
{
//Do Something that uses BackLightIntensity
}
}
"the factory method is for multiple concrete classes that have the exact same implementation as the abstract base class [interface] and do not add their own properties."
No, speaking more practical, than theorical, the factory method can provide you with objects of concrete classes, in which the concrete classes, must have some common methods and interfaces, but, also some additional specific attributes.
Sometimes I use a method that creates the same class object every time I called, and I need to call it several times, and sometimes I use a method that create several different class objects, and that maybe be confusing, maybe another question.
And, your further comment about a switch sentence, with many options, when using the factory pattern, you usually provide an identifier for the concrete class / concrete object. This can be a string, an integer, an special type id, or an enumerated type.
You could use an integer / enum ID instead, and use a collection to lookup for the concrete class.
You can still leverage a factory. The point of a factory IMO is to put all the heavy lifting of constructing your various TVs in one place. To say categorically "a factory is for multiple concrete classes that have the exact same implementation as the abstract base class" is forgetting about polymorphism.
There is no law that says you cannot use a factory pattern because the sub classes declare unique properties and methods. But the more you can make use of polymorphism, the more a factory pattern makes sense. Also as a general guideline, IMHO, the more complexity that must go into constructing from the base the better off you are in the long run using a factory because you are "encapsulating change" - that is, constructing concrete classes is likely to change due to differing requirements and inherent construction complexity (a design analysis decision, to be sure) . And that change is in a single class - the factory.
Try this: Define everything in the abstract class and then for a given TV subclass either write concrete-specific code, and for those that don't apply write some standard "I don't do that" code.
Think about all the things your TVs do in generic terms: turn on, turn off, etc. Write a virtual method shell in the base class for all the generic things a TV does - this is a simple example of the template method pattern by the way. Then override these in the concrete classes as appropriate.
There are other things you can do in the base class to make it more fundgeable (that's a technical term meaning "reference subclasses as the base class, but do sub-classy things").
Define delegate methods (very powerful yet under-utilized)
use params[] for dynamic method parameter lists
Make Property delegates
Static methods
Declare Properties and methods "abstract" - forces sub-class implementation, vis-a-vis "virtual"
Hide inherited stuff in the sub class (generally using "new" keyword to communicate that it's on purpose)
If construction parameters are numerous or complex, create a class specifically designed to pass configuration to the factory's build method.
public class TVFactory {
public TV BuildTV(Brands thisKind) {
TV newSet;
switch (thisKind) {
case Brands.Samsung :
Samsung aSamsungTV = new Samsung();
aSamsungTV.BacklightIntensity = double.MinVal;
aSamsungTV.AutoShutdownTime = 45; //oops! I made a magic number. My bad
aSamsungTV.SetAutoShutDownTime = new delegate (newSet.SetASDT);
newSet = aSamsungTV;
break;
. . .
} // switch
}
//more build methods for setting specific parameters
public TV BuildTV (Brands thisKind, string Size) { ... }
// maybe you can pass in a set of properties to exactly control the construction.
// returning a concrete class reference violates the spirit of object oriented programming
public Sony BuildSonyTV (...) {}
public TV BuildTV (Brands thisKind, Dictionary buildParameters) { ... }
}
public class TV {
public string Size { get; set; }
public string ScreenType { get; set; }
public double BackLightIntensity { get; set; }
public int AutoShutdownTime { get; set; }
//define delegates to get/set properties
public delegate int GetAutoShutDownTime ();
public delegate void SetAutoShutDownTime (object obj);
public virtual TurnOn ();
public virtural TurnOff();
// this method implemented by more than one concrete class, so I use that
// as an excuse to declare it in my base.
public virtual SomeSonyPhillipsOnlything () { throw new NotImplementedException("I don't do SonyPhillips stuff"); }
}
public class Samsung : TV {
public Samsung() {
// set the properties, delegates, etc. in the factory
// that way if we ever get new properties we don't open umpteen TV concrete classes
// to add it. We're only altering the TVFactory.
// This demonstrates how a factory isolates code changes for object construction.
}
public override void TurnOn() { // do stuff }
public override void TurnOn() { // do stuff }
public void SamsungUniqueThing () { // do samsung unique stuff }
internal void SetASDT (int i) {
AutoShutDownTime = i;
}
}
// I like enumerations.
// No worries about string gotchas
// we get intellense in Visual Studio
// has a documentation-y quality
enum Brands {
Sony
,Samsung
,Phillips
}