my problem is this:
I have a base class
public abstract class ViewModelBase
which contains an abstract method "RegisterCommands"
protected abstract void RegisterCommands();
All my Derived classes must, obviously, implements this method, for example my LoginViewModel has
protected override void RegisterCommands()
{
LoginCommand?
.Configure(
execute: (msg) => { Login(User); },
canExecute: (x) => { return CanLogin(); }
);
}
and call it when class is instantiated, but i don't want call this method in every derived class constructor (if I have 100 derived classes I must call RegisterCommand 100 times).
Normal solution is call RegisterCommand in the base class constructor
protected abstract void RegisterCommands();
public ViewModelBase()
{
RegisterCommands();
}
and this usually works (even if I do not know if it's a good practice) but...but...
in my scenario, in all the RegisterCommands methods I use my ICustomCommand objects, which are initialized in the derived class constructor with dependency injection
public class LoginViewModel : ViewModelBase
{
private ICustomCommand _loginCommand;
public ICustomCommand LoginCommand
{
get
{
return _loginCommand;
}
set
{
_loginCommand = value;
}
}
public LoginViewModel(ICustomCommand loginCommand)
{
_loginCommand = loginCommand;
}
protected override void RegisterCommands()
{
LoginCommand?
.Configure(
execute: (msg) => { Login(User); },
canExecute: (x) => { return CanLogin(); }
);
}
So, because base class constructor is called before derived class constructor, I can't call RegisterCommands() in base class constructor (because my ICustomCommands are not initialized yet in derived class so RegisterCommands() try to use my ICustomCommand which are still null).
I know that is not possible call derived class constructor before base class constructor, so what could be a valid, simple and clean solution to call RegisterCommands in all derived class calling this command in only one point?
thanks for answer
UPDATE:
As I said, RegisterCommands() is plural because every derived class could have N ICustomCommand objects
So I can have
LoginCommand for my LoginViewModel
SaveCommand, DeleteCommand for another ViewModel
etc.
One solution I think now is to remove ICustomCommand initialization from constructor and resolve it "on the fly" in getter property trough a static Resolver class, something like this
public ICustomCommand LoginCommand
{
get
{
if(_loginCommand == null)
MyStaticResolver.Resolve<ICustomCommand>();
return _loginCommand;
But I'm still not convinced
If you use interfaces to represent your commands, you could pass them to the base class and expose a method to retrieve the commands. Your Registration method can then use them as needed:
public abstract class ViewModelBase
{
public ViewModelBase(params ICustomCommand[] commands)
{
_commands = commands;
RegisterCommands();
}
private IEnumerable<ICustomCommand> _commands;
protected abstract void RegisterCommands();
//This method gets you the commands
protected T GetCommand<T>() where T : ICustomCommand
{
var command = _commands.FirstOrDefault(c => typeof(T).IsAssignableFrom(c.GetType()));
return (T)command ;
}
}
public class LoginViewModel : ViewModelBase
{
public LoginViewModel(ILoginCommand command):base(command)
{
}
protected override void RegisterCommands()
{
//Get the command from the base class
var command = GetCommand<ILoginCommand>();
command?
.Configure(
execute: (msg) => { Login(User); },
canExecute: (x) => { return CanLogin(); }
);
}
}
public class LoginCommand : ILoginCommand
{
}
public interface ILoginCommand : ICustomCommand
{
}
EDIT
Ive rephrased the question so it better reflects what im trying to do
I'm trying to create a suite of classes that all inherit from 1 "superclass" or "baseclass".
However i'm looking for a way around having to implement the code for each method, in every single class since it seems to be theres a lot of duplication.
Here is the Super class:
public abstract class WebObject
{
string Id { get; set; }
string Name { get; set; }
public void Click() { Console.WriteLine("Clicking object"); }
public string GetAttribute() { return "An attribute"; }
public void SetAttribute(string attribute, string value)
{
//code to set attribute
}
}
I've also created a couple of interfaces:
interface IReadable
{
string GetText();
}
interface IWriteable
{
void SetText(string value);
}
Here is an example derived class:
public class TextBox: WebObject, IWriteable, IReadable
{
}
Of course the above class contains an error. It does not implement IWriteable or IReadable.
So I could do something like:
public class TextBox: WebObject, IWriteable, IReadable
{
public void SetText(string value)
{
//Implemented code
}
public string GetText()
{
//Implemented code
return "some value";
}
}
Which would compile fine...
However the problem here is that SetText and GetText contain a lot of code. I don't want to have to copy this every single time I want to implement the method. Id rather just write the code once and have it called any time I need to use that method.
I know we cant do multiple inheritance in C# and Java. So my original thought was simply to create a suite of static classes with the code for SetText and GetText Shown here:
public static class Setter
{
public static void SetText(string value)
{
//Code to set text
}
}
public static class Getter
{
public static string GetText()
{
//Code to get text
return "";
}
}
Then changing my TextBox class to the following:
public class TextBox: WebObject, IWriteable, IReadable
{
public void SetText(string value)
{
Setter.SetText(value);
}
public string GetText()
{
return Getter.GetText();
}
}
I cant help but feel this is a pretty long winded solution. It accomplishes what I want in that TextBox has the vanilla methods plus the 2 it implements itself.
But my question is, can I achieve the same goal using a more concise design?
Footnotes
Each object actually implements several of common methods. Take TextBox, ComboBox and SelectBox they all should be able to SetText, however only CombBox and SelectBox should be able to use Select.
The cleanest way to do what you are asking is to implement protected helper methods within your base class that decompose the problem of "a lot of duplication" into smaller pieces that can be composed in your concrete method implementations, like this:
public abstract class WebObject {
protected void SetTextImpl() { /* Implementation */ }
protected void GetTextImpl() { /* Implementation */ }
}
Then in your derived classes, implement only the applicable interfaces and appropriate methods:
public class TextBox: WebObject, IWriteable, IReadable {
public void SetText() { SetTextImpl(); }
public void GetText() { GetTextImpl(); }
}
public class Span: WebObject, IReadable {
public void GetText() { GetTextImpl(); }
}
If you know that all the subclasses will be IReadable, you can simplify further:
public abstract class WebObject : IReadable {
protected void SetTextImpl() { /* Implementation */ }
protected void GetTextImpl() { /* Implementation */ }
// Implement IReadable -- this could be combined with GetTextImpl() but
// is implemented separately for consistency.
public void GetText() { GetTextImpl(); }
}
public class TextBox: WebObject, IWriteable {
public void SetText() { SetTextImpl(); }
}
public class Span: WebObject, IReadable {
}
If the code for those two methods will always be the same or mostly the same, you could create another abstract class (ex: WebObjectReadWrite) that inherits from WebObject and implements the interface.
public abstract class WebObjectReadWrite : WebObject, IReadable, IWritable
{
// Could be made virtual if some subclasses need to overwrite default implementation.
public void Read()
{
// Implementation
}
// Could be made virtual if some subclasses need to overwrite default implementation.
public void Write()
{
// Implementation
}
}
public class TextBox : WebObjectReadWrite
{
}
This could, however, lead to multiple inheritance problems or inheritance relationships that don't make sense. Another option is to use the strategy pattern (in way) to delegate the read / write operations to other classes that can be reused.
public class TextBox : WebObject, IReadable, IWriteable
{
private IReadable _readable = new TextReader();
private IWriteable _writeable = new TextWriter();
public void Read()
{
_readable.Read();
}
public void Write()
{
_writable.Write();
}
}
public class Span : WebObject, IReadable
{
// Reused class.
private IReadable _readable = new TextReader();
public void Read()
{
_readable.Read();
}
}
public class TextReader : IReadable
{
public void Read()
{
// Reusable implementation
}
}
This isn't quite the strategy pattern because you are not allowing the caller to choose the implementation of IReadable and IWriteable. However, it does allow you to reuse IReadable and IWriteable classes.
This cracks my head, I hope somebody will have the wiliness to find a solution.
Right below is a simplified code of the situation. The objective here is, that I wanth a separate, reusable library and to have the option of customizing these classes for each implementation. So i went for inheritance:
namespace Library {
//a class that holds stuff together
public class Core<THandler> where THandler:Handler
{
public THandler handler;
public string text = "Something";
}
//class that react for extern events, say a keyboard events
public class Handler
{
protected object core;
public Handler(object _core) {
core = _core;
}
protected virtual void OnEvent() {
//how to access 'core.text' ??
var a = (Core<Handler>)core; //raises System.InvalidCastException
// since 'core' actualy contains
// an instance of MyCore
}
}
}
namespace MyImplementation {
public class MyCore : Library.Core<MyHandler>
{
}
public class MyHandler : Library.Handler
{
protected override void OnEvent() {
base.OnEvent();
//and what's the preferable option for accessing 'core' here?
var a = (MyCore)core; //I use this
}
}
}
Since Handler.core contains an instance of MyCore, how can one access this object inside Hanlder.OnEventmethod?
You are better off with using interfaces to bind Core and Handler to each other. You can still keep Core<T> generic. Generic type contraints wouldn't allow you to declare circular dependencies, which would otherwise be necessary to make your core work.
Note that the root cause for the problematic cast to be invalid is not that core instance is MyCore from your example, but because MyCore inherits from Core<MyHandler> and not Core<Handler>.
In case, for some reason, you'd insist of keeping the current design, you can make Handler generic as well, passing in its ancestor as type parameter, and fixing the cast like this:
public class Handler<THandler> where THandler : Handler<THandler>
{
protected object core;
public Handler(object _core) {
core = _core;
}
public virtual void OnEvent() {
// this works
var a = (Core<THandler>)core;
}
}
So, to make it a bit more type-safe and avoid casts, the constructor should look like this:
protected Core<THandler> core;
public Handler(Core<THandler> _core) {
core = _core;
}
The MyHandler declaration would then, quite naturally, look like this:
public class MyHandler : Handler<MyHandler>
{
…
}
The best approach here (in my mind, anyway) is to create an interface for the methods and properties that you need to access in Core.
For example, something similar to the following:
namespace Library {
public interface ICore {
string text {get; set;}
}
//a class that holds stuff together
public class Core<THandler> : ICore where THandler : Handler
{
public THandler handler;
private string m_Text = "Something";
public string text
{
get
{
return m_Text;
}
set
{
m_Text = value;
}
}
}
//class that react for extern events, say a keyboard events
public class Handler
{
protected ICore core;
public Handler(object _core) {
core = (ICore)_core;
}
protected virtual void OnEvent() {
Debug.WriteLine(core.text);
}
}
}
namespace MyImplementation {
public class MyCore : Library.Core<MyHandler>
{
}
public class MyHandler : Library.Handler
{
protected override void OnEvent() {
base.OnEvent();
//and what's the preferable option for accessing 'core' here?
var a = (MyCore)core; //I use this
}
}
}
The cast failes because Core is not covariant. Classes in general can not be covariant. Only interfaces and delegates can be covariant.
To reach the expected behaviour you can define the Core class as an interface with a out parameter, like below
public interface ICore<out T>where T:Handler
{
T Handler {get;}
string Text { get; }
}
I have the following classes
class GridBase
{
public object DataSource { get; set; }
}
class GenericGrid<T> : GridBase
{
public new T DataSource { get; set; }
}
Both GridBase and Generic Grid classes can be instantiated and one can descend from either as well.
Is this considered the correct/accepted way to implement such a hierarchy?
Or should you go the extra mile and implement it like the following
class GridBase
{
protected object dataSource;
public object DataSource { get { return dataSource; } set { dataSource = value; } }
}
class GenericGrid<T> : GridBase
{
public new T DataSource { get { return (T)dataSource; } set { dataSource = value; } }
}
The same applies to non generic classes when a property is re-introduced in a descendant, I'm just using a generic example here.
Another case and question
abstract class SomeBase
{
protected abstract void DoSomething();
}
class Child : SomeBase
{
protected override void DoSomething()
{
/* Some implementation here */
}
}
The situation here is that framework "X" declares SomeBase allowing you to define your own descendants. The classes they create (at run time) then descend from your class (Child in the this case). However, they don't call your DoSomething() method, from their implementation of DoSomething().
On their part, they can't blindly call base.Dosomething() either because the typical case is that the class they generate normally descends from SomeBase and since the method is abstract that's not valid. (Personally, I don't like this behavior in C#).
But anyway, is that good or accepted design, that is not calling base.xxx(), especially when the the "intent" seems to contradict?
EDIT From a framework design perspective. Is it ok/acceptable that it does this? If not how would it be designed so as to either prevent such a case or better impart their intent (in both cases).
I would prefer something like this:
interface IGrid {
object DataSource { get; }
}
interface IGrid<T> {
T DataSource { get; }
}
public Grid : IGrid {
public object DataSource { get; private set; }
// details elided
}
public Grid<T> : IGrid<T> {
public T DataSource { get; private set; }
object IGrid.DataSource { get { return this.DataSource; } }
// details elided
}
Note that I am NOT inheriting from Grid.
For the DataSource question I prefer the following pattern
abstract class GridBase {
public abstract object DataSource { get; }
}
class GenericGrid<T> : GridBase {
private T m_data;
public override object DataSource {
get { return m_data; }
}
public T DataSourceTyped {
get { return m_data; }
set { m_data = value; }
}
}
Reasons
Having the GridBase.DataSource member be writable is type unsafe. It allows me to break the contract of GenericGrid<T> by setting the value to a non-T instance
This is more of a matter of opinion but I dislike the use of new because it often confuses users. I prefer the suffix ~Type" for this scenario
This only requires the data be stored once
Doesn't require any unsafe casting.
EDIT OP corrected that GridBase and GenericGrid are both usable types
In that case I would say you need to reconsider your design a bit. Having them both as usable types opens you up to very easy to expose type errors.
GenericGrid<int> grid = new GenericGrid<int>();
GridBase baseGrid = grid;
baseGrid.DataSource = "bad";
Console.Write(grid.DataSource); // Error!!!
The design will be a lot more reliable if separate the storage from the access of the values in a manner like my original sample. You could extend it further with the following code to have a usable non-generic container
class Grid : GridBase {
private objecm m_data;
public override object DataSource {
get { return m_data; }
}
public object DataSourceTyped {
get { return m_data; }
set { m_data = value; }
}
}
The second form of the generic inheritance (casting the base class' attribute) is more correct as it does not violate Liskov Substitution Principle. It is conceivable that an instance of the generic class is cast into base class and accessing Data through the base class points to a different property. You will need to keep both in sync in order for the derived class to be substitutable for the base class.
Alternatively, you can implement some sort of a strategy pattern where the base class asks for the Data property from the derived class, in order to avoid awkward downcasting. This is what I had in mind:
public class Base {
private readonly object m_Data; //immutable data, as per JaredPar suggestion that base class shouldn't be able to change it
publlic Base(object data) {
m_Data = data;
}
protected virtual object GetData() {return m_Data;}
public Object DataSource {get {return GetData();}}
}
public class Derived<T> : Base {
private T m_Data;
public Derived():base(null){}
protected override object GetData() {return m_Data;}
protected new T Data {return m_Data;}
}
With regards to the second question, I am note sure I understand the question. Sound like the problem you are having is to with the framework not calling the abstract method when it generates a proxy at runtime, which is always legal in abstract classes, as the only way for that code to execute is through a derived class which must override the abstract method.
It's weird that this is the first time I've bumped into this problem, but:
How do you define a constructor in a C# interface?
Edit
Some people wanted an example (it's a free time project, so yes, it's a game)
IDrawable
+Update
+Draw
To be able to Update (check for edge of screen etc) and draw itself it will always need a GraphicsDeviceManager. So I want to make sure the object has a reference to it. This would belong in the constructor.
Now that I wrote this down I think what I'm implementing here is IObservable and the GraphicsDeviceManager should take the IDrawable...
It seems either I don't get the XNA framework, or the framework is not thought out very well.
Edit
There seems to be some confusion about my definition of constructor in the context of an interface. An interface can indeed not be instantiated so doesn't need a constructor. What I wanted to define was a signature to a constructor. Exactly like an interface can define a signature of a certain method, the interface could define the signature of a constructor.
You can't. It's occasionally a pain, but you wouldn't be able to call it using normal techniques anyway.
In a blog post I've suggested static interfaces which would only be usable in generic type constraints - but could be really handy, IMO.
One point about if you could define a constructor within an interface, you'd have trouble deriving classes:
public class Foo : IParameterlessConstructor
{
public Foo() // As per the interface
{
}
}
public class Bar : Foo
{
// Yikes! We now don't have a parameterless constructor...
public Bar(int x)
{
}
}
As already well noted, you can't have constructors on an Interface. But since this is such a highly ranked result in Google some 7 years later, I thought I would chip in here - specifically to show how you could use an abstract base class in tandem with your existing Interface and maybe cut down on the amount of refactoring needed in the future for similar situations. This concept has already been hinted at in some of the comments but I thought it would be worth showing how to actually do it.
So you have your main interface that looks like this so far:
public interface IDrawable
{
void Update();
void Draw();
}
Now create an abstract class with the constructor you want to enforce. Actually, since it's now available since the time you wrote your original question, we can get a little fancy here and use generics in this situation so that we can adapt this to other interfaces that might need the same functionality but have different constructor requirements:
public abstract class MustInitialize<T>
{
public MustInitialize(T parameters)
{
}
}
Now you'll need to create a new class that inherits from both the IDrawable interface and the MustInitialize abstract class:
public class Drawable : MustInitialize<GraphicsDeviceManager>, IDrawable
{
GraphicsDeviceManager _graphicsDeviceManager;
public Drawable(GraphicsDeviceManager graphicsDeviceManager)
: base (graphicsDeviceManager)
{
_graphicsDeviceManager = graphicsDeviceManager;
}
public void Update()
{
//use _graphicsDeviceManager here to do whatever
}
public void Draw()
{
//use _graphicsDeviceManager here to do whatever
}
}
Then just create an instance of Drawable and you're good to go:
IDrawable drawableService = new Drawable(myGraphicsDeviceManager);
The cool thing here is that the new Drawable class we created still behaves just like what we would expect from an IDrawable.
If you need to pass more than one parameter to the MustInitialize constructor, you can create a class that defines properties for all of the fields you'll need to pass in.
A very late contribution demonstrating another problem with interfaced constructors. (I choose this question because it has the clearest articulation of the problem). Suppose we could have:
interface IPerson
{
IPerson(string name);
}
interface ICustomer
{
ICustomer(DateTime registrationDate);
}
class Person : IPerson, ICustomer
{
Person(string name) { }
Person(DateTime registrationDate) { }
}
Where by convention the implementation of the "interface constructor" is replaced by the type name.
Now make an instance:
ICustomer a = new Person("Ernie");
Would we say that the contract ICustomer is obeyed?
And what about this:
interface ICustomer
{
ICustomer(string address);
}
You can't.
Interfaces define contracts that other objects implement and therefore have no state that needs to be initialized.
If you have some state that needs to be initialized, you should consider using an abstract base class instead.
I was looking back at this question and I thought to myself, maybe we are aproaching this problem the wrong way. Interfaces might not be the way to go when it concerns defining a constructor with certain parameters... but an (abstract) base class is.
If you create a base class with a constructor on there that accepts the parameters you need, every class that derrives from it needs to supply them.
public abstract class Foo
{
protected Foo(SomeParameter x)
{
this.X = x;
}
public SomeParameter X { get; private set }
}
public class Bar : Foo // Bar inherits from Foo
{
public Bar()
: base(new SomeParameter("etc...")) // Bar will need to supply the constructor param
{
}
}
It is not possible to create an interface that defines constructors, but it is possible to define an interface that forces a type to have a paramerterless constructor, though be it a very ugly syntax that uses generics... I am actually not so sure that it is really a good coding pattern.
public interface IFoo<T> where T : new()
{
void SomeMethod();
}
public class Foo : IFoo<Foo>
{
// This will not compile
public Foo(int x)
{
}
#region ITest<Test> Members
public void SomeMethod()
{
throw new NotImplementedException();
}
#endregion
}
On the other hand, if you want to test if a type has a paramerterless constructor, you can do that using reflection:
public static class TypeHelper
{
public static bool HasParameterlessConstructor(Object o)
{
return HasParameterlessConstructor(o.GetType());
}
public static bool HasParameterlessConstructor(Type t)
{
// Usage: HasParameterlessConstructor(typeof(SomeType))
return t.GetConstructor(new Type[0]) != null;
}
}
Hope this helps.
One way to solve this problem i found is to seperate out the construction into a seperate factory. For example I have an abstract class called IQueueItem, and I need a way to translate that object to and from another object (CloudQueueMessage). So on the interface IQueueItem i have -
public interface IQueueItem
{
CloudQueueMessage ToMessage();
}
Now, I also need a way for my actual queue class to translate a CloudQueueMessage back to a IQueueItem - ie the need for a static construction like IQueueItem objMessage = ItemType.FromMessage. Instead I defined another interface IQueueFactory -
public interface IQueueItemFactory<T> where T : IQueueItem
{
T FromMessage(CloudQueueMessage objMessage);
}
Now I can finally write my generic queue class without the new() constraint which in my case was the main issue.
public class AzureQueue<T> where T : IQueueItem
{
private IQueueItemFactory<T> _objFactory;
public AzureQueue(IQueueItemFactory<T> objItemFactory)
{
_objFactory = objItemFactory;
}
public T GetNextItem(TimeSpan tsLease)
{
CloudQueueMessage objQueueMessage = _objQueue.GetMessage(tsLease);
T objItem = _objFactory.FromMessage(objQueueMessage);
return objItem;
}
}
now I can create an instance that satisfies the criteria for me
AzureQueue<Job> objJobQueue = new JobQueue(new JobItemFactory())
hopefully this helps someone else out someday, obviously a lot of internal code removed to try to show the problem and solution
One way to solve this problem is to leverage generics and the new() constraint.
Instead of expressing your constructor as a method/function, you can express it as a factory class/interface. If you specify the new() generic constraint on every call site that needs to create an object of your class, you will be able to pass constructor arguments accordingly.
For your IDrawable example:
public interface IDrawable
{
void Update();
void Draw();
}
public interface IDrawableConstructor<T> where T : IDrawable
{
T Construct(GraphicsDeviceManager manager);
}
public class Triangle : IDrawable
{
public GraphicsDeviceManager Manager { get; set; }
public void Draw() { ... }
public void Update() { ... }
public Triangle(GraphicsDeviceManager manager)
{
Manager = manager;
}
}
public TriangleConstructor : IDrawableConstructor<Triangle>
{
public Triangle Construct(GraphicsDeviceManager manager)
{
return new Triangle(manager);
}
}
Now when you use it:
public void SomeMethod<TBuilder>(GraphicsDeviceManager manager)
where TBuilder: IDrawableConstructor<Triangle>, new()
{
// If we need to create a triangle
Triangle triangle = new TBuilder().Construct(manager);
// Do whatever with triangle
}
You can even concentrate all creation methods in a single class using explicit interface implementation:
public DrawableConstructor : IDrawableConstructor<Triangle>,
IDrawableConstructor<Square>,
IDrawableConstructor<Circle>
{
Triangle IDrawableConstructor<Triangle>.Construct(GraphicsDeviceManager manager)
{
return new Triangle(manager);
}
Square IDrawableConstructor<Square>.Construct(GraphicsDeviceManager manager)
{
return new Square(manager);
}
Circle IDrawableConstructor<Circle>.Construct(GraphicsDeviceManager manager)
{
return new Circle(manager);
}
}
To use it:
public void SomeMethod<TBuilder, TShape>(GraphicsDeviceManager manager)
where TBuilder: IDrawableConstructor<TShape>, new()
{
// If we need to create an arbitrary shape
TShape shape = new TBuilder().Construct(manager);
// Do whatever with the shape
}
Another way is by using lambda expressions as initializers. At some point early in the call hierarchy, you will know which objects you will need to instantiate (i.e. when you are creating or getting a reference to your GraphicsDeviceManager object). As soon as you have it, pass the lambda
() => new Triangle(manager)
to subsequent methods so they will know how to create a Triangle from then on. If you can't determine all possible methods that you will need, you can always create a dictionary of types that implement IDrawable using reflection and register the lambda expression shown above in a dictionary that you can either store in a shared location or pass along to further function calls.
The generic factory approach still seems ideal. You would know that the factory requires a parameter, and it would just so happen that those parameters are passed along to the constructor of the object being instantiated.
Note, this is just syntax verified pseudo code, there may be a run-time caveat I'm missing here:
public interface IDrawableFactory
{
TDrawable GetDrawingObject<TDrawable>(GraphicsDeviceManager graphicsDeviceManager)
where TDrawable: class, IDrawable, new();
}
public class DrawableFactory : IDrawableFactory
{
public TDrawable GetDrawingObject<TDrawable>(GraphicsDeviceManager graphicsDeviceManager)
where TDrawable : class, IDrawable, new()
{
return (TDrawable) Activator
.CreateInstance(typeof(TDrawable),
graphicsDeviceManager);
}
}
public class Draw : IDrawable
{
//stub
}
public class Update : IDrawable {
private readonly GraphicsDeviceManager _graphicsDeviceManager;
public Update() { throw new NotImplementedException(); }
public Update(GraphicsDeviceManager graphicsDeviceManager)
{
_graphicsDeviceManager = graphicsDeviceManager;
}
}
public interface IDrawable
{
//stub
}
public class GraphicsDeviceManager
{
//stub
}
An example of possible usage:
public void DoSomething()
{
var myUpdateObject = GetDrawingObject<Update>(new GraphicsDeviceManager());
var myDrawObject = GetDrawingObject<Draw>(null);
}
Granted, you'd only want the create instances via the factory to guarantee you always have an appropriately initialized object. Perhaps using a dependency injection framework like AutoFac would make sense; Update() could "ask" the IoC container for a new GraphicsDeviceManager object.
You could do this with generics trick, but it still is vulnerable to what Jon Skeet wrote:
public interface IHasDefaultConstructor<T> where T : IHasDefaultConstructor<T>, new()
{
}
Class that implements this interface must have parameterless constructor:
public class A : IHasDefaultConstructor<A> //Notice A as generic parameter
{
public A(int a) { } //compile time error
}
The purpose of an interface is to enforce a certain object signature. It should explicitly not be concerned with how an object works internally. Therefore, a constructor in an interface does not really make sense from a conceptual point of view.
There are some alternatives though:
Create an abstract class that acts as a minimal default implementation.
That class should have the constructors you expect implementing classes
to have.
If you don't mind the overkill, use the AbstractFactory pattern and
declare a method in the factory class interface that has the required
signatures.
Pass the GraphicsDeviceManager as a parameter to the Update and Draw methods.
Use a Compositional Object Oriented Programming framework to pass the GraphicsDeviceManager into the part of the object that requires it. This is a pretty experimental solution in my opinion.
The situation you describe is not easy to handle in general. A similar case would be entities in a business application that require access to the database.
you don't.
the constructor is part of the class that can implement an interface. The interface is just a contract of methods the class must implement.
It would be very useful if it were possible to define constructors in interfaces.
Given that an interface is a contract that must be used in the specified way. The following approach might be a viable alternative for some scenarios:
public interface IFoo {
/// <summary>
/// Initialize foo.
/// </summary>
/// <remarks>
/// Classes that implement this interface must invoke this method from
/// each of their constructors.
/// </remarks>
/// <exception cref="InvalidOperationException">
/// Thrown when instance has already been initialized.
/// </exception>
void Initialize(int a);
}
public class ConcreteFoo : IFoo {
private bool _init = false;
public int b;
// Obviously in this case a default value could be used for the
// constructor argument; using overloads for purpose of example
public ConcreteFoo() {
Initialize(42);
}
public ConcreteFoo(int a) {
Initialize(a);
}
public void Initialize(int a) {
if (_init)
throw new InvalidOperationException();
_init = true;
b = a;
}
}
One way to force some sort of constructor is to declare only Getters in interface, which could then mean that the implementing class must have a method, ideally a constructor, to have the value set (privately) for it.
While you can't define a constructor signature in an interface, I feel it's worth mentioning that this may be a spot to consider an abstract class. Abstract classes can define unimplemented (abstract) method signatures in the same way as an interface, but can also have implemented (concrete) methods and constructors.
The downside is that, because it is a type of class, it cannot be used for any of the multiple inheritance type scenarios that an interface can.
I use the following pattern to make it bulletproof.
A developer who derives his class from the base can't accidentally create a public accessible constructor
The final class developer are forced to go through the common create method
Everything is type-safe, no castings are required
It's 100% flexible and can be reused everywhere, where you can define your own base
class.
Try it out you can't break it without making modifications to the base classes (except
if you define an obsolete flag without error flag set to true, but even then you end up with a warning)
public abstract class Base<TSelf, TParameter>
where TSelf : Base<TSelf, TParameter>, new()
{
protected const string FactoryMessage = "Use YourClass.Create(...) instead";
public static TSelf Create(TParameter parameter)
{
var me = new TSelf();
me.Initialize(parameter);
return me;
}
[Obsolete(FactoryMessage, true)]
protected Base()
{
}
protected virtual void Initialize(TParameter parameter)
{
}
}
public abstract class BaseWithConfig<TSelf, TConfig>: Base<TSelf, TConfig>
where TSelf : BaseWithConfig<TSelf, TConfig>, new()
{
public TConfig Config { get; private set; }
[Obsolete(FactoryMessage, true)]
protected BaseWithConfig()
{
}
protected override void Initialize(TConfig parameter)
{
this.Config = parameter;
}
}
public class MyService : BaseWithConfig<MyService, (string UserName, string Password)>
{
[Obsolete(FactoryMessage, true)]
public MyService()
{
}
}
public class Person : Base<Person, (string FirstName, string LastName)>
{
[Obsolete(FactoryMessage,true)]
public Person()
{
}
protected override void Initialize((string FirstName, string LastName) parameter)
{
this.FirstName = parameter.FirstName;
this.LastName = parameter.LastName;
}
public string LastName { get; private set; }
public string FirstName { get; private set; }
}
[Test]
public void FactoryTest()
{
var notInitilaizedPerson = new Person(); // doesn't compile because of the obsolete attribute.
Person max = Person.Create(("Max", "Mustermann"));
Assert.AreEqual("Max",max.FirstName);
var service = MyService.Create(("MyUser", "MyPassword"));
Assert.AreEqual("MyUser", service.Config.UserName);
}
EDIT:
And here is an example based on your drawing example that even enforces interface abstraction
public abstract class BaseWithAbstraction<TSelf, TInterface, TParameter>
where TSelf : BaseWithAbstraction<TSelf, TInterface, TParameter>, TInterface, new()
{
[Obsolete(FactoryMessage, true)]
protected BaseWithAbstraction()
{
}
protected const string FactoryMessage = "Use YourClass.Create(...) instead";
public static TInterface Create(TParameter parameter)
{
var me = new TSelf();
me.Initialize(parameter);
return me;
}
protected virtual void Initialize(TParameter parameter)
{
}
}
public abstract class BaseWithParameter<TSelf, TInterface, TParameter> : BaseWithAbstraction<TSelf, TInterface, TParameter>
where TSelf : BaseWithParameter<TSelf, TInterface, TParameter>, TInterface, new()
{
protected TParameter Parameter { get; private set; }
[Obsolete(FactoryMessage, true)]
protected BaseWithParameter()
{
}
protected sealed override void Initialize(TParameter parameter)
{
this.Parameter = parameter;
this.OnAfterInitialize(parameter);
}
protected virtual void OnAfterInitialize(TParameter parameter)
{
}
}
public class GraphicsDeviceManager
{
}
public interface IDrawable
{
void Update();
void Draw();
}
internal abstract class Drawable<TSelf> : BaseWithParameter<TSelf, IDrawable, GraphicsDeviceManager>, IDrawable
where TSelf : Drawable<TSelf>, IDrawable, new()
{
[Obsolete(FactoryMessage, true)]
protected Drawable()
{
}
public abstract void Update();
public abstract void Draw();
}
internal class Rectangle : Drawable<Rectangle>
{
[Obsolete(FactoryMessage, true)]
public Rectangle()
{
}
public override void Update()
{
GraphicsDeviceManager manager = this.Parameter;
// TODo manager
}
public override void Draw()
{
GraphicsDeviceManager manager = this.Parameter;
// TODo manager
}
}
internal class Circle : Drawable<Circle>
{
[Obsolete(FactoryMessage, true)]
public Circle()
{
}
public override void Update()
{
GraphicsDeviceManager manager = this.Parameter;
// TODo manager
}
public override void Draw()
{
GraphicsDeviceManager manager = this.Parameter;
// TODo manager
}
}
[Test]
public void FactoryTest()
{
// doesn't compile because interface abstraction is enforced.
Rectangle rectangle = Rectangle.Create(new GraphicsDeviceManager());
// you get only the IDrawable returned.
IDrawable service = Circle.Create(new GraphicsDeviceManager());
}