Correct way to encapsulate through generic interfaces - c#

My application consist of server and client, which are independant. They communicate through objects created and modified by server. Client is provided with read-only interfaces of this objects. As far as I know, that's the correct way to keep encapsulation in OOP. See example:
// Client-side
interface IBox<T> where T : ITool
{
IEnumerable<T> Tools { get; }
}
interface ITool
{
void Use();
}
// Server-side
class Box : IBox<Tool>
{
public List<Tool> ToolList = new List<Tool>();
public IEnumerable<ITool> Tools
{
get { return ToolList; }
}
}
class Tool : ITool
{
string _msg = "default msg";
public string Msg
{
get { return _msg; }
set { _msg = value; }
}
public void Use()
{
Console.WriteLine("Tool used! Msg: {0}", _msg);
}
}
As you see, I have to use generics, because my objects form a hierarchy.
That looked nice, until I've decided to add a Room class with interface IRoom, which have to generalize not only IBox, but ITool too:
interface IRoom<B, T>
where B : IBox<T>
where T : ITool
{
IEnumerable<B> Boxes { get; }
}
class Room : IRoom<Box, Tool>
{
public List<Box> BoxList = new List<Box>();
public IEnumerable<Box> Boxes
{
get { return BoxList; }
}
}
Now, imagine that we have a Room consist of not only boxes. I need at least 3 collections of absolutely different things there, which are collections of several types too. So, there must be a huge tree, and my root class become something like: Room : IRoom<Box, Tool1, Tool2, Tool3, Wardrobe, Coat, Jeans, Hat, Table, Computer, Book, Pen>
I'm not sure, that is right. So, I'm asking, what is true OOP-way of implementing my task? (with no reflection, breaking encapsulation, type casting or other bad tricks)

Starting with the .NET Framework 4 and C# 4 you can use IEnumerable's covariance and just avoid using generics.
// Client-side
interface IBox
{
IEnumerable<ITool> Tools { get; }
}
interface ITool
{
void Use();
}
// Server-side
class Box : IBox
{
public List<Tool> ToolList = new List<Tool>();
public IEnumerable<ITool> Tools
{
get { return ToolList; } // With .NET 3.5 and earlier cast here is neccessary to compile
// Cast to interfaces shouldn't be so much of a performance penalty, I believe.
}
}
class Tool : ITool
{
string _msg = "default msg";
public string Msg
{
get { return _msg; }
set { _msg = value; }
}
public void Use()
{
Console.WriteLine("Tool used! Msg: {0}", _msg);
}
}
interface IRoom
{
IEnumerable<IBox> Boxes { get; }
}
class Room : IRoom
{
public List<Box> BoxList = new List<Box>();
public IEnumerable<IBox> Boxes
{
get { return BoxList; } // and here...
}
}
Covariance and contravariance in generics described here: http://msdn.microsoft.com/en-us/library/dd799517.aspx

Related

Factory Design Pattern implementation in console application

I am new to programming and learning through online stuff and you guys, nowadays! I am reading about Factory Design Pattern and tried to implement in the very basic project, I have a solution that has two projects one projects contain interfaces, and the other contains implementation, I have read about factories but unfortunately, I have no idea how to implement in my project, In one project, I have 2 interfaces IBasicCars and ILuxuryCars, IluxuryCars implementing IBasicCars and then in the second project I have a class that inherits from ILuxuryCars and implement all of its methods and IBasicCars methods and properties, here is my code for that class.
public class LuxuryCars : ILuxuryCar
{
private string _color { get; set; }
public string Color
{
get
{
return _color;
}
set
{
_color = value;
}
}
private int _model { get; set; }
public int Model
{
get
{
return _model;
}
set
{
_model = value;
}
}
private string _make { get; set; }
public string Make
{
get
{
return _make;
}
set
{
_make = value;
}
}
public void Break()
{
Console.WriteLine("This is the basic function of all cars !!!");
}
public void CruiseControl()
{
Console.WriteLine("This is the luxury feature for luxury cars !!!");
}
public void Drive()
{
Console.WriteLine("This is the basic function of all cars !!!");
}
public void Navigation()
{
Console.WriteLine("This is the luxury feature for luxury cars !!!");
}
public void Park()
{
Console.WriteLine("This is the basic function of all cars !!!");
}
}
now I have another class "FactoryObject" in that project that has nothing in it right now, can someone please tell me to do I implement the factory design pattern?
that is how I am calling these methods in main method
static void Main(string[] args)
{
ILuxuryCar lc = new LuxuryCars();
lc.Color = "Black";
lc.Make = "Honda";
lc.Model = 2007;
Console.WriteLine("Car color is: {0} Made by: {1} Model is: {2}", lc.Color, lc.Make, lc.Model);
lc.Navigation();
lc.CruiseControl();
lc.Break();
lc.Drive();
lc.Park();
Console.WriteLine();
IBasicCar b = new LuxuryCars();
b.Color = "Red";
b.Make = "Alto";
b.Model = 2019;
Console.WriteLine("Car color is: {0} Made by: {1} Model is: {2}", lc.Color, lc.Make, lc.Model);
lc.Break();
lc.Drive();
lc.Park();
Console.ReadLine();
}
A very simple factory could be
public interface ICarFactory{
ICar Create();
}
public class BasicCarFactory : ICarFactory{
public ICar Create() => new BasicCar();
}
public class LuxuryCarFactory : ICarFactory{
public ICar Create() => new LuxuryCar();
}
This makes it more complicated to create a car, but the important bit is that components that need to create new car objects can do so without knowing what kind of car is created.
You might for example check the license at startup, and depending on the license create different factories that you hand of to all the other components. This way you have the license check at one single place, instead of spread out over different components.
In simple cases you might not need a separate inteface, a Func<ICar> might be sufficient.

C# OOP Composition and Generalization at the same time

This might be a simple/basic OOP question, but I still cannot figure out how to solve it.
I had the following problem during an interview : make an UML class diagram and write the basic code for a "smart"phone which contains the functionalities of a telephone and of an mp3 player. We've got with the following (accepted) solution :
class Telephone
{
public string name { get; set; }
public Telephone()
{
name = "name telephone";
}
}
class MP3
{
public string name { get; set; }
public MP3()
{
name = "name mp3";
}
}
And the "smart"phone class :
class TelephoneMP3
{
public Telephone tel;
public MP3 mp3;
public TelephoneMP3()
{
tel = new Telephone();
mp3 = new MP3();
}
}
As you can see, we have a composition relation between the TelephoneMP3 and the Telephone/MP3 classes.
But, using this code, the TelephoneMP3 is not a Telephone and the TelephoneMP3 is not an MP3 either, which is not logical. So, what changes should I make in order to make this valid ? For example, this kind of test :
if (telMp3 is Telephone)
{
Console.WriteLine("TelephoneMP3 is telephone");
}
if (telMp3 is MP3)
{
Console.WriteLine("TelephoneMP3 is mp3");
}
The modifications could be made using the following remarks :
Telephone / MP3 / TelephoneMP3 must remain classes (all 3 of them)
I could add interfaces / other classes if necessary
TelephoneMP3 must not duplicate all the functionalities from a Telephone / MP3 (for example during an inheritance from an interface where the TelephoneMP3 will be obliged to write the code from all the interface's members)
Thank you in advance
Since C# doesn't support multiple inheritance, consider using interfaces instead:
public interface Phone{ ... }
public interface Mp3{ ... }
public class Telephone : Phone{ ... }
public class Mp3Player : Mp3{ ... }
public class Smartphone : Phone, Mp3{ ... }
This way Smartphone is both Phone and Mp3. If you are in need to write a method which operates on a Telephone, use the Phone interface instead. This way you'll be able to pass either Telephone or Smartphone as an argument.
There are some good answers here. The answers which say to use interfaces are good, and that's what the interviewer is likely looking for. However, I would consider simply denying the premise that the "is-a-kind-of" relationship being satisified is a good idea. Rather, I would consider using a service provider organization:
public interface ITelephone { ... }
internal class MyTelephone : ITelephone { ... }
public interface IMusicPlayer { ... }
internal class MyPlayer : IMusicPlayer { ... }
public interface IServiceProvider
{
T QueryService<T>() where T : class;
}
internal class MyDevice : IServiceProvider
{
MyTelephone phone = new MyTelephone();
MyPlayer player = new MyPlayer();
public T QueryService<T>() where T : class
{
if (typeof(T) == typeof(ITelephone)) return (T)(object)phone;
if (typeof(T) == typeof(IPlayer)) return (T)(object)player;
return null;
}
}
Now a caller has a MyDevice in hand via its IServiceProvider interface. You ask it
ITelephone phone = myDevice.QueryService<ITelephone>();
and if phone is non-null, then the device can act like a phone. But
myDevice is ITelephone
is false. The device is not a phone, it knows how to find you something that acts like a phone.
For more in this vein, study plug-in architectures such as MAF.
It is almost similar to the other answers, but..
I think it has the best accuracy regarding the inheritance hierarchy.
internal class Program
{
private static void Main(string[] args)
{
var telephone = new Telephone();
Console.WriteLine(telephone.Name);
telephone.OutboundCall("+1 234 567");
Console.WriteLine("Am I a Telephone? {0}", telephone is Telephone);
Console.WriteLine("Am I a MP3? {0}", telephone is MediaPlayer3);
Console.WriteLine("Am I a Smartphone? {0}", telephone is Smartphone);
Console.WriteLine("Do I Have Telephone Capabilities? {0}", telephone is ITelephone);
Console.WriteLine("Do I Have MP3 Capabilities? {0}", telephone is IMediaPlayer3);
Console.WriteLine();
var mp3 = new MediaPlayer3();
Console.WriteLine(mp3.Name);
mp3.PlaySong("Lalala");
Console.WriteLine("Am I a Telephone? {0}", mp3 is Telephone);
Console.WriteLine("Am I a MP3? {0}", mp3 is MediaPlayer3);
Console.WriteLine("Am I a Smartphone? {0}", mp3 is Smartphone);
Console.WriteLine("Do I Have Telephone Capabilities? {0}", mp3 is ITelephone);
Console.WriteLine("Do I Have MP3 Capabilities? {0}", mp3 is IMediaPlayer3);
Console.WriteLine();
var smartphone = new Smartphone();
Console.WriteLine(smartphone.Name);
smartphone.OutboundCall("+1 234 567");
smartphone.PlaySong("Lalala");
Console.WriteLine("Am I a Telephone? {0}", smartphone is Telephone);
Console.WriteLine("Am I a MP3? {0}", smartphone is MediaPlayer3);
Console.WriteLine("Am I a Smartphone? {0}", smartphone is Smartphone);
Console.WriteLine("Do I Have Telephone Capabilities? {0}", smartphone is ITelephone);
Console.WriteLine("Do I Have MP3 Capabilities? {0}", smartphone is IMediaPlayer3);
Console.ReadKey();
}
public interface IDevice
{
string Name { get; }
}
public interface ITelephone : IDevice
{
void OutboundCall(string number);
}
public interface IMediaPlayer3 : IDevice
{
void PlaySong(string filename);
}
public class Telephone : ITelephone
{
public string Name { get { return "Telephone"; } }
public void OutboundCall(string number)
{
Console.WriteLine("Calling {0}", number);
}
}
public class MediaPlayer3 : IMediaPlayer3
{
public string Name { get { return "MP3"; } }
public void PlaySong(string filename)
{
Console.WriteLine("Playing Song {0}", filename);
}
}
public class Smartphone : ITelephone, IMediaPlayer3
{
private readonly Telephone telephone;
private readonly MediaPlayer3 mp3;
public Smartphone()
{
telephone = new Telephone();
mp3 = new MediaPlayer3();
}
public string Name { get { return "Smartphone"; } }
public void OutboundCall(string number)
{
telephone.OutboundCall(number);
}
public void PlaySong(string filename)
{
mp3.PlaySong(filename);
}
}
}
Program Output:
Telephone
Calling +1 234 567
Am I a Telephone? True
Am I a MP3? False
AM I a Smartphone? False
Do I Have Telephone Capabilities? True
Do I Have MP3 Capabilities? False
MP3
Playing Song Lalala
Am I a Telephone? False
Am I a MP3? True
AM I a Smartphone? False
Do I Have Telephone Capabilities? False
Do I Have MP3 Capabilities? True
Smartphone
Calling +1 234 567
Playing Song Lalala
Am I a Telephone? False
Am I a MP3? False
AM I a Smartphone? True
Do I Have Telephone Capabilities? True
Do I Have MP3 Capabilities? True
I think this interview question is not (as should be all interview questions) about the challenge itself. The coding exercise of merging two classes via composition could be answered with a textbook. This challenge is a subtle trick question, and I propose that the point is to get you to discuss why. At least that's what I would want from my interviewees.
This test:
if(telMp3 is Telephone && telMp3 is MP3) {
...is the real problem. Why must you meet this criteria? This test completely voids the purpose of building objects out of composition. It demands that the objects are implemented in a specific way. It shows that the existing class implementations are already tightly coupled to the codebase (if they cannot be done away with). These requirements mean that SOLID principles were not followed, because you can't just fulfill the methods of a base type, you have to actually be the base type. That's no good.
As other answers have said, the solution would be to use interfaces. Then you can pass your object to any method that requires the interface. This kind of usage would require a test like so:
if (telMp3 is IPhone && telMp3 is IMp3) {
...but you can't do that, because of the limitation of your challenge. That means that out there in the rest of your code, people have been writing methods that explicitly depend on the specific types Telephone and MP3. That is the real problem.
In my opinion, the correct answer to this challenge is to say that the codebase fails the test. The specific fallout in your challenge is irrelvant; you need to change the requirements of the challenge before you can solve it properly. An interviewee would who recognize this fact would pass the test with flying colors.
You can use explicit interface implemenations as well to limit usage of the shared variable Name. That way you would have to cast to the interface to access it. You can still have public properties / methods from the interface.
Composition is still used, but the SmartPhone has control over the implementations of their properties / methods.
To me, this would be the easiest implementation to work with, because I rarely want to use both the implementation from the mp3player and the phone, but rather one of them. Also, I still have full control over what happens when the interfaces methods are called on the SmartPhone.
class User
{
void UseSmartPhone(SmartPhone smartPhone)
{
// Cannot access private property 'Name' here
Console.WriteLine(smartPhone.Name);
// Cannot access explicit implementation of 'IMp3Player.Play'
smartPhone.Play();
// You can send the phone to the method that accepts an IMp3Player though
PlaySong(smartPhone);
// This works fine. You are sure to get the Phone name here.
Console.WriteLine(((IPhone)smartPhone).Name);
// This works fine, since the Call is public in SmartPhone.
smartPhone.Call();
}
void CallSomeone(IPhone phone)
{
phone.Call();
}
void PlaySong(IMp3Player player)
{
player.Play();
}
}
class SmartPhone : IPhone, IMp3Player
{
private Phone mPhone;
private Mp3Player mMp3Player;
public SmartPhone()
{
mPhone = new Phone();
mMp3Player = new Mp3Player();
}
public void Call()
{
mPhone.Call();
}
string IPhone.Name
{
get { return mPhone.Name; }
}
string IMp3Player.Name
{
get { return mMp3Player.Name; }
}
void IMp3Player.Play()
{
mMp3Player.Play();
}
}
class Mp3Player
{
public string Name { get; set; }
public void Play()
{
}
}
class Phone
{
public string Name { get; set; }
public void Call()
{
}
}
interface IPhone
{
string Name { get; }
void Call();
}
interface IMp3Player
{
string Name { get; }
void Play();
}
How about this solution:
public interface ITelephone
{
string Name{get;}
void MakeCall();
}
public interface IMp3
{
string Name { get; }
void Play(string filename);
}
public abstract class BaseTelephone : ITelephone
{
public virtual string Name { get { return "Telephone"; } }
void MakeCall()
{
// code to make a call.
}
}
public class MyMp3Player : IMp3
{
public string Name { get { return "Mp3 Player"; } }
public void Play(string filename)
{
// code to play an mp3 file.
}
}
public class SmartPhone : BaseTelephone, IMp3
{
public override string Name { get { return "SmartPhone"; } }
private IMp3 Player { get { return _Player; } set { _Player = value; } }
private IMp3 _Player = new MyMp3Player();
public void Play(string filename) { Player.Play(filename); }
}
This way the smart phone can also be an Mp3 player, but internally it has an Mp3 player that it uses to play the music. The internal player can be swapped for a new one (eg. upgrade) by using the SmartPhone Player property.
The code for the phone is only written once, in the base phone class. The code for the Mp3 player is only written once also - in the MyMp3Player class.
Use the strategy pattern (used some shortcuts below, you'll get the gist).
public class Device {
private List<App> apps;
public Device() {
this.apps = new List<App>();
this.apps.Add(new Mp3Player());
this.apps.Add(new Telephone());
}
}
public class Mp3Player implements App {...}
public class Telephone implements App {...}
public interface App {...}
Disclaimer: my native tongue is PHP, forgive me any non C# coding standards etc etc.
You could use implicit casting
class TelephoneMP3
{
public Telephone tel;
public MP3 mp3;
public TelephoneMP3()
{
tel = new Telephone();
mp3 = new MP3();
}
public static implicit operator Telephone(TelephoneMP3 telemp3) {
return telemp3.tel;
}
public static implicit operator MP3(TelephoneMP3 telemp3) {
return telemp3.mp3;
}
}
It won't pass the exact test that you proposed, but you can do
var teleMp3 = new TelephoneMP3();
Telephone t = teleMp3;
You are trying to model a product hierarchy, in which a given product may have its own specific properties, as well as being composed of standard sub-products. This is indeed an example of the composition pattern. I suggest introducing a base interface for any product component, then creating specific interfaces for telephone, MP3 player and smartphone products.
In the traditional composition pattern each node may contain an arbitrary list of components to which subcomponents can be added or removed, however in your data model it appears more useful for each specific type of product to specify its precise children, then provide a generic method to iterate over them. This allows for specific (sub)components of a specified type/interface to be easily queryable throughout the product hierarchy.
I've also introduced an interface for a GPS product since all new phones contain built-in GPS receivers -- just to illustrate how to work with recursive hierarchies of components.
public interface IProductComponent
{
string Name { get; set; }
IEnumerable<IProductComponent> ChildComponents { get; }
IEnumerable<IProductComponent> WalkAllComponents { get; }
TProductComponent UniqueProductComponent<TProductComponent>() where TProductComponent : class, IProductComponent;
}
public interface ITelephone : IProductComponent
{
IGps Gps { get; }
}
public interface IMp3Player : IProductComponent
{
}
public interface IGps : IProductComponent
{
double AltitudeAccuracy { get; }
}
public interface ISmartPhone : IProductComponent
{
ITelephone Telephone { get; }
IMp3Player Mp3Player { get; }
}
These interfaces could then be implemented by a parallel set of classes:
public abstract class ProductComponentBase : IProductComponent
{
string name;
protected ProductComponentBase(string name)
{
this.name = name;
}
#region IProductComponent Members
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public virtual IEnumerable<IProductComponent> ChildComponents
{
get
{
return Enumerable.Empty<IProductComponent>();
}
}
public IEnumerable<IProductComponent> WalkAllComponents
{
get
{
yield return this;
foreach (var child in ChildComponents)
{
foreach (var subChild in child.WalkAllComponents)
yield return subChild;
}
}
}
public TProductComponent UniqueProductComponent<TProductComponent>() where TProductComponent : class, IProductComponent
{
TProductComponent foundComponent = null;
foreach (var child in WalkAllComponents.OfType<TProductComponent>())
{
if (foundComponent == null)
foundComponent = child;
else
throw new Exception("Duplicate products found of type " + typeof(TProductComponent).Name);
}
return foundComponent;
}
#endregion
}
public class Telephone : ProductComponentBase, ITelephone
{
IGps gps = new Gps();
public Telephone()
: base("telephone")
{
}
#region ITelephone Members
public IGps Gps
{
get
{
return gps;
}
}
#endregion
IEnumerable<IProductComponent> BaseChildComponents
{
get
{
return base.ChildComponents;
}
}
public override IEnumerable<IProductComponent> ChildComponents
{
get
{
if (Gps != null)
yield return Gps;
foreach (var child in BaseChildComponents)
yield return child;
}
}
}
public class Gps : ProductComponentBase, IGps
{
public Gps()
: base("gps")
{
}
#region IGps Members
public double AltitudeAccuracy
{
get { return 100.0; }
}
#endregion
}
public class TelephoneMP3 : ProductComponentBase, ISmartPhone
{
ITelephone telephone;
IMp3Player mp3Player;
public TelephoneMP3()
: base("TelephoneMP3")
{
this.telephone = new Telephone();
this.mp3Player = new MP3();
}
IEnumerable<IProductComponent> BaseChildComponents
{
get
{
return base.ChildComponents;
}
}
public override IEnumerable<IProductComponent> ChildComponents
{
get
{
if (Telephone != null)
yield return Telephone;
if (Mp3Player != null)
yield return Mp3Player;
foreach (var child in BaseChildComponents)
yield return child;
}
}
#region ISmartPhone Members
public ITelephone Telephone
{
get { return telephone; }
}
public IMp3Player Mp3Player
{
get { return mp3Player; }
}
#endregion
}
public class MP3 : ProductComponentBase, IMp3Player
{
public MP3()
: base("mp3Player")
{
}
}
As new product component types are added (or subclassed), they override the "ChildComponents" of their parent and return their domain specific children.
Having done this, you can (recursively) query the product hierarchy for components of a given type for your use. For instance:
var accuracy = smartPhone.UniqueProductComponent<IGps>().AltitudeAccuracy
or
bool hasPhone = (component.UniqueProductComponent<ITelephone>() != null)
This combination of generalization and composition avoids duplicating code while making explicit the type of sub-components that should be found in any given product. It also avoids the burden of making all higher-level products proxy the interfaces of their standard children, passing all calls on to them.
Contrary to all the other answers I am quite confident the way this question is asked makes it impossible. The reason is the following :
You explicitly state
But, using this code, the TelephoneMP3 is not a Telephone and the TelephoneMP3 is not an MP3 either, which is not logical. So, what changes should I make in order to make this valid ?
Seeing the word "is" makes me immediately think of the "is" operator. I immediately assume that this is what you really want.
You then go on later to say the following:
Telephone / MP3 / TelephoneMP3 must remain classes (all 3 of them)
Well sure we can do the following:
interface ITelephone { }
class Telephone
{
public string name { get; set; }
public Telephone()
{
name = "name telephone";
}
}
interface IMP3 { }
class MP3 : IMP3
{
public string name { get; set; }
public MP3()
{
name = "name mp3";
}
}
class TelephoneMP3 : ITelephone, IMP3
{
public Telephone tel;
public MP3 mp3;
public TelephoneMP3()
{
tel = new Telephone();
mp3 = new MP3();
}
}
But we still have one problem. The word "is". Since we must keep the classes TelephoneMP3, Telephone and MP3 and C# does not support multiply inheritance it simply is not possible.
To Illustrate my point:
public class Program
{
static void Main(string[] args)
{
TelephoneMP3 t = new TelephoneMP3();
Console.WriteLine((t is TelephoneMP3)? true:false);
Console.WriteLine((t is ITelephone) ? true : false);
Console.WriteLine((t is IMP3) ? true : false);
Console.WriteLine((t is Telephone) ? true : false);
Console.WriteLine((t is MP3) ? true : false);
Console.ReadLine();
}
}
This will give you
True
True
True
False
False
In other words TelephoneMP3 "is" an ITelephone. TelephoneMP3 "is" an IMP3; however, it is not possible for a TelephoneMP3 to be both a MP3 and a Telephone.
C# does not support multiple inheritance, you need to use interfaces and abstract class for common implementations , You can do the follwing :
Edit : I have add more details to my answer
abstract class BaseDevice
{
public string name { get; set; }
public void Print()
{
Console.WriteLine("{0}", name );
}
}
public interface IPhone
{
void DoPhone();
}
public interface IMP3
{
void DoMP3();
}
class Telephone :BaseDevice , IPhone
{
public Telephone()
{
name = "name telephone";
}
}
class MP3 : BaseDevice , IMP3
{
public MP3()
{
name = "name mp3";
}
}
class telMp3 : BaseDevice , IMP3, IPhone
{
private Telephone _tel;
private MP3 _mp3;
public telMp3()
{
name = "name telMp3";
}
public void DoPhone()
{
_tel.DoPhone();
}
public void DoMP3()
{
_mp3.DoMP3();
}
}

must implement EITHER interface A OR interface B (exactly one)

I have an interface that looks like this:
public interface IOpportunity
{
string Name { get; }
string Description { get; }
ILocation Location { get; }
}
public interface ILocation : IHierarchicalEntity
{
int OpptyCount { get; }
}
public interface IHierarchicalEntity
{
string SID { get; }
string Name { get; }
}
However, I want the ILocation object to also implement ONE of these interfaces:
public interface IHierarchicalEntityWithParentNames : IHierarchicalEntity
{
/// <summary>
/// Returns the lowest level that this heirarchy goes (0 for a flat hierarchy, 1 for a two-level etc.)
/// </summary>
int LeafLevel { get; }
/// <summary>
/// Returns the name of the Segment for the given level (0 for a root node, n for leaf node, where n = LeafLevel)
/// </summary>
/// <param name="level"></param>
/// <returns></returns>
string GetNameForLevel(int level);
}
public interface IHierarchicalEntityWithParentIds : IHierarchicalEntity
{
IHierarchicalEntityWithParentIds ParentEntity { get; }
string ParentSID { get; }
}
Due to the nature of the code I am writing, I cannot combine these interfaces into one interface that has some sort of GetParent method
In the code that consumes these interfaces, I have two classes - one that consumes the ILocation object if it is an IHierarchicalEntityWithParentNames and another if it is an IHierarchicalEntityWithParentIds
How would I lay out the interfaces (perhaps I have to have some abstract classes) to support having this "one or the other" design?
You can't. You either explicitly implement an interface, or you don't. What you're describing is effectively "either method A or method B will exist," but that's not a concept that exists in C# (or any other language that I'm aware of!).
The closest you'll be able to get would be to throw an exception in the code that consumes your interface if the class doesn't also implement one of the other two interfaces.
Alternatively, I imagine you could have a base class whose constructor will throw an exception if it doesn't also implement one or other of the interfaces. This would give you an earlier check, but it's still a runtime check and, personally, I think it's a horrible idea.
I believe you are over-constraining the true problem. This is very similar to an issue I encountered in my game engine, where coordinates on a hex grid can be either in the canonical reference frame (axes at 120 degress, convenient for most internal game functions) or in the rectangular (user) reference frame with axes at 90 degrees (convenient for most user-visiable game functions).
I addressed this by buidlng a single class Coords that explicitly implements both interfaces ICoordsCanon and ICoordsUser. The actual coordinates are lazily stored and evaluated with an automated conversion like this:
protected static IntMatrix2D MatrixUserToCanon;
protected IntVector2D VectorCanon {
get { return ! isCanonNull ? _vectorCanon
: VectorUser * MatrixUserToCanon; }
set { _vectorCanon = value; isUserNull = true; }
} IntVector2D _vectorCanon;
bool isCanonNull;
protected static IntMatrix2D MatrixCanonToUser;
protected IntVector2D VectorUser {
get { return ! isUserNull ? _vectorUser
: VectorCanon * MatrixCanonToUser; }
set { _vectorUser = value; isCanonNull = true; }
} IntVector2D _vectorUser;
bool isUserNull;
The constructor for Coords is private, with public static functions NewUserCoords(...) and NewCanonCoords(...) defined.
Alhough the implementation is not truly either ... or ..., it APPEARS to be implemented so to the application. Most application usages either works with ICoordsCanon objects, or with ICoordsUser objects; the two methods ICoordsCanon.User() and ICoordsUser.Canon() exist for converting between the two as necessary.
By popular demand, here are the interface definitions and implementations.
public interface ICoordsUser {
int X { get; }
int Y { get; }
IntVector2D Vector { get; set; }
ICoordsCanon Canon { get; }
//ICoordsUser Clone();
string ToString();
int Range(ICoordsUser coords);
IEnumerable<NeighbourCoords> GetNeighbours(Hexside hexsides);
}
public partial class Coords {
int ICoordsUser.X { get { return VectorUser.X; } }
int ICoordsUser.Y { get { return VectorUser.Y; } }
IntVector2D ICoordsUser.Vector { get { return VectorUser; }
set { VectorUser=value; } }
ICoordsCanon ICoordsUser.Canon { get { return this; } }
//ICoordsUser ICoordsUser.Clone() { return NewUserCoords(VectorUser); }
string ICoordsUser.ToString() { return VectorUser.ToString(); }
IEnumerable<NeighbourCoords> ICoordsUser.GetNeighbours(Hexside hexsides) {
return GetNeighbours(hexsides);
}
int ICoordsUser.Range(ICoordsUser coords) { return Range(coords.Canon); }
}
}
and
public interface ICoordsCanon {
int X { get; }
int Y { get; }
IntVector2D Vector { get; set; }
ICoordsCustom Custom { get; }
ICoordsUser User { get; }
//ICoordsCanon Clone();
string ToString();
int Range(ICoordsCanon coords);
IEnumerable<NeighbourCoords> GetNeighbours(Hexside hexsides);
}
public partial class Coords {
int ICoordsCanon.X { get { return VectorCanon.X; } }
int ICoordsCanon.Y { get { return VectorCanon.Y; } }
IntVector2D ICoordsCanon.Vector { get { return VectorCanon; }
set { VectorCanon=value; } }
ICoordsUser ICoordsCanon.User { get { return this; } }
ICoordsCustom ICoordsCanon.Custom { get { return this; } }
//ICoordsCanon ICoordsCanon.Clone() { return NewCanonCoords(this.VectorCanon); }
string ICoordsCanon.ToString() { return VectorCanon.ToString(); }
IEnumerable<NeighbourCoords> ICoordsCanon.GetNeighbours(Hexside hexsides) {
return GetNeighbours(hexsides);
}
int ICoordsCanon.Range(ICoordsCanon coords) { return Range(coords); }
}
Note that I have not included the entire definition of class Coords, as that would simply be far too large a post. The entire implementation is availabel on CodePlex here: HexGrid Utilities
I am not aware of any way to enforce this at compile time. I think you would have to make this a runtime check by using a base class that throws an exception if both interfaces are implemented.
However, that won't stop someone from bypassing your base class and implementing the interfaces themselves, and I know of no way to prevent that.
You can try Code Contracts. Post-condition. Smth like this
[ContractClassFor(typeof(IOpportunity))]
public abstract class OpportunityContract : IOpportunity
{
public ILocation Location
{
get { Contract.Ensures(Contract.Result<ILocation>() is IHierarchicalEntityWithParentNames || Contract.Result<ILocation>() is IHierarchicalEntityWithParentIds); }
}
}

Is it possible to bind different interfaces to the same instance of a class implementing all of them?

I have the following (simplified) situation: I have two interfaces
interface IAmAnInterface
{
void DoSomething();
}
and
interface IAmAnInterfaceToo
{
void DoSomethingElse();
}
and a class implementing both:
class IAmAnImplementation: IAmAnInterface, IAmAnInterfaceToo
{
public IAmAnImplementation()
{
}
public void DoSomething()
{
}
public void DoSomethingElse()
{
}
}
Now I bind the same class to both interfaces using Ninject. Since I want the same instance of IAmAnImplementation beeing used for IAmAnInterface as well as IAmAnInterfaceToo it's clear that I need some kind of singleton. I played around with ninject.extensions.namedscope as well as InScope() but had no success. My last try was:
Bind<IAmAnImplementation>().ToSelf().InSingletonScope();
Bind<IAmAnInterface>().To<IAmAnImplementation>().InSingletonScope();
Bind<IAmAnInterfaceToo>().To<IAmAnImplementation>().InSingletonScope();
But unfortunately when I request an instance of my test class via kernel.Get<IDependOnBothInterfaces>(); it in fact uses different instances of IAmAnImplementation.
class IDependOnBothInterfaces
{
private IAmAnInterface Dependency1 { get; set; }
private IAmAnInterfaceToo Dependency2 { get; set; }
public IDependOnBothInterfaces(IAmAnInterface i1, IAmAnInterfaceToo i2)
{
Dependency1 = i1;
Dependency2 = i2;
}
public bool IUseTheSameInstances
{
get { return Dependency1 == Dependency2; } // returns false
}
}
Is there a way tell Ninject to use the same instance of IAmAnImplementation for IAmAnInterface as well as IAmAnInterfaceToo?
It is very easy using V3.0.0
Bind<I1, I2, I3>().To<Impl>().InSingletonScope();

Is It possible to use the second part of this code for repository patterns and generics

Is there any issues in using version 2,to get the same results as version 1.
Or is this just bad coding.
Any Ideas
public class Customer
{
public int CustomerID { get; set; }
public string EmailAddress { get; set; }
int Age { get; set; }
}
public interface ICustomer
{
void AddNewCustomer(Customer Customer);
void AddNewCustomer(string EmailAddress, int Age);
void RemoveCustomer(Customer Customer);
}
public class BALCustomer
{
private readonly ICustomer dalCustomer;
public BALCustomer(ICustomer dalCustomer)
{
this.dalCustomer = dalCustomer;
}
public void Add_A_New_Customer(Customer Customer)
{
dalCustomer.AddNewCustomer(Customer);
}
public void Remove_A_Existing_Customer(Customer Customer)
{
dalCustomer.RemoveCustomer(Customer);
}
}
public class CustomerDataAccess : ICustomer
{
public void AddNewCustomer(Customer Customer)
{
// MAKE DB CONNECTION AND EXECUTE
throw new NotImplementedException();
}
public void AddNewCustomer(string EmailAddress, int Age)
{
// MAKE DB CONNECTION AND EXECUTE
throw new NotImplementedException();
}
public void RemoveCustomer(Customer Customer)
{
// MAKE DB CONNECTION AND EXECUTE
throw new NotImplementedException();
}
}
// VERSION 2
public class Customer_New : DataRespository<CustomerDataAccess>
{
public int CustomerID { get; set; }
public string EmailAddress { get; set; }
public int Age { get; set; }
}
public class DataRespository<T>
where T:class,new()
{
private T item = new T();
public T Execute { get { return item; } set { item = value; } }
public void Update()
{
//TO BE CODED
}
public void Save()
{
//TO BE CODED
}
public void Remove()
{
//TO BE CODED
}
}
class Program
{
static void Main(string[] args)
{
Customer_New cus = new Customer_New()
{
Age = 10,
EmailAddress = "this#demo.com"
};
cus.Save();
cus.Execute.RemoveCustomer(new Customer());
// Repository Version
Customer customer = new Customer()
{
EmailAddress = "new#demo.com",
CustomerID = 10
};
BALCustomer bal = new BALCustomer(new CustomerDataAccess());
bal.Add_A_New_Customer(customer);
}
}
You have a lot of things going on that aren't making a lot of sense.
First of all, the names of properties should always be a noun (singular or plural) or a "being" verb like Is* or Has*. These are properties of an object, and should be similar to what you would say in response to a question like "Would you please describe your desk?" Execute is an operation, and should therefore be a method. Likewise, your naming conventions in Version 1 should be PascalCased which means no underscores and the first letter of all words should be capitalized. These aren't die-hard truths, but they are considered OOP common C# coding standards.
Secondly, the code in your main method isn't actually implementing anything in your generic class. The only thing your class is actually doing is creating an instance of CustomerDataAccess. The Save() method won't do anything, unless you specifically are able to call item.Save() In order to use your Save, Update, Delete functionality on your generic class, your CustomerDataAccess class will have to implement an interface expected by your generic class. For instance:
public interface IDataAccess<T> : where T : YourBaseObject {
public void Update(T item);
public void Save(T item);
public void Remove(T item);
}
public class Customer : YourBaseObject {
public int CustomerID { get; set; }
public string EmailAddress { get; set; }
public int Age { get; set; }
}
public class CustomerDataAccess :
DataRespository<IDataAccess<Customer>> {
public void PerformCustomerOnlyAction(Customer customer) {
/* do stuff */
}
}
Now, you can create a generic class that handles basic CRUD functionality, and all other functionality is accessible through the BaseRepository property.
/* e.g. T = IDataAccess<Customer>, K = Customer */
public class DataRespository<T>
where T : IDataAccess<K>, new()
where K : YourBaseObject, new()
{
private T _base;
public T BaseRepository {
get {
if(_base == null)
_base = Activator.CreateInstance<T>();
return _base;
}
}
public void Update(K item) { /* functionality for YourBaseObject */ }
public void Save(K item) { /* functionality for YourBaseObject */ }
public void Remove(K item) { /* functionality for YourBaseObject */ }
}
class Program
{
static void Main(string[] args)
{
var repository = new CustomerDataAccess();
Customer c = new Customer {
Age = 10,
EmailAddress = "this#demo.com"
};
repository.Save(c);
// This pass-through is no longer needed, but shown as example
// repository.BaseRepository.PerformCustomerOnlyAction(c);
repository.PerformCustomerOnlyAction(c);
}
}
NOTE I did the above code from scratch/memory. The generic type constraints may not work exactly as I have them.
ASP.NET 3.5 Unleashed by Stephen Walther has a couple of chapters on creating a repository pattern which is setup similarly to what you're trying to accomplish in Version 2. He also splits processing up between a business logic layer and a data access layer. Although the book is huge (nearly 2000 pages) and many of the code examples are redundant or better left as part of the CD, he goes pretty in-depth for beginner-to-intermediate range. It's available used on Amazon for around $25.
I think while implementing object model of your application you just have to ask yourself a number of questions as though you are make object design review of your collegue code.
Why CustomerAccessLayer implements interface? Is there will be a number of layers implementing this Interface. Or maybe you are expecting any polymorph behaviour from classes implements this interface? Or maybe you will separate interface to standalone module and will provide its functionality though any kind of service?
Why do you need BALCustomer class? Why you could not make calls directly to CustomerAccesLayer? And, have i already spoke about codesyle? :)
If DataRepository have a generic behaviour and will provide a number of AccessLayers throw Execute property why it is have its own methods?
I think could be continued... I hope you've catch my point?

Categories

Resources