I have an interface which defines a class to be serializable to a byte array.
public interface IByteSerializable
{
byte[] GetBytes();
}
The natural partner to this is a deserialize method, which I want to return an object that implements IByteSerializable.
I'm stuggling with how to design such an interface.
This doesn't seem to make sense:
public interface IByteSerializable
{
byte[] GetBytes();
IByteSerializable GetObject(byte[] bytes);
}
Because the implementation of GetObject() can't be static and it doesn't make sense to use a dummy IByteSerializable object just to call the GetObject() method to deserialize the actual object I'm after.
It also doesn't seem to make sense to do this:
public interface IByteSerializableFactory
{
IByteSerializable GetObject(byte[] bytes);
}
A Factory class could solve the problem, but this feels like it will result in class explosion. Also, the details of how a given IByteSerializable subclass are serialized then deserialized are co-dependent, so it makes sense to keep them in the same place, and not in two different classes. Obviously, the exact process required to deserialize a given IByteSerializable object depends entirely on how that object's GetBytes() method was written.
Is there a common design or pattern I can use to solve this issue?
There are a lot of different opinions on interfaces, classes, and patterns when it comes to your question. My personal preference would be implementing an interface with a byte[] property and an abstract class with a virtual method (or even losing the interface altogether, which might not be an option for you and does not play well with DI and unit testing):
public interface IByteSerializable
{
byte[] SerializableByteObject { get; }
}
public abstract class ByteSerializable : IByteSerializable
{
public byte[] SerializableByteObject { get; }
protected virtual byte[] GetBytes() {
return SerializableByteObject;
}
public abstract IByteSerializable GetObject();
//{ // You can make this method virtual and use Impl method:
// GetObjectImpl(SerializableByteObject);
//}
protected internal IByteSerializable GetObjectImpl(byte[] bytes) {
// If you need a default implementation (GetObject() should be protected virtual then)
// return IByteSerializable...;
}
}
I want to stress that interfaces VS abstract classes is an endless discussion. If you can do stuff without implementing interfaces and use just abstract classes - I would strongly recommend doing so.
Update 3/18/17: to reply to a comment (defining behavior is the purpose of an interface) and explain how I see it adding the explanation below.
In this scenario, the "behavior" we are defining is "An object should be convertible into a byte array. Conversion result should be convertible back into the same object." So we're actually defining behavior for an object and for a byte array (because after an object was deserialized - it's no longer the same object, it's just a byte array).
From my perspective, that's pure factory pattern scenario.
// Let's define an interface for our serializable type of objects factory
public interface IByteSerializableFactory<T>
{
T CreateFromBytes(byte[] objectDataToUse);
byte[] CovertToBytes(T objectToConvert);
}
// Interface for any class that needs a serialization factory
// This is not even necessary, but I like it to enforce people to implement simple methods that reference the factory.
public interface IByteSerializable<T>
{
IByteSerializableFactory<T> GetFactory();
}
// Now a moment comes for us to have this kind of class. We need to build a factory first (because our interface requires a GetFactory() implementation. We can lose the IByteSerializable interface altogether, but then we lose a way to let people know which factory should be used.
public class SomeBaseClassSerializationFactory : IByteSerializableFactory<SomeBaseClass>
{
public SomeBaseClass CreateFromBytes(byte[] objectDataToUse) { //...
return new SomeClass();
}
public byte[] CovertToBytes(SomeBaseClass objectToConvert) { //...
return new byte[1];
}
}
// We have a factory, let's implement a class.
public abstract class SomeBaseClass : IByteSerializable<SomeBaseClass>
{
public virtual IByteSerializableFactory<SomeBaseClass> GetFactory() {
return new SomeBaseClassSerializationFactory();
}
}
public class SomeClass : SomeBaseClass {
// Now we're independent. Our derived classes do not need to implement anything.
// If the way the derived class is serialized is different - we simply override the method
}
Update 2 3/18/17: to reply to a comment under a different answer (generic implementation with simple use of interface).
Unfortunately, there will be no clean way to do it. There is a dirty (my personal opinion: "BAD BAD BAD!") way by using some cheating, defining classes that define serialization methods and using reflection to return correct type. The example below will require a lot of custom logic in the serialization method for using correct fields with different types:
// You define an enum with action and a dictionary with a collection of serialization methods.
public enum SerializationAction {
ToBytes,
ToObject
}
// It can also be an enum, but it's easier to test with a collection of strings.
public static readonly string[] SerializationKindList = new string[] {
"FirstKind",
"SecondKind"
};
// This generic class can have an implementation of all the handlers. Additional switching can be done by type, or reflection can be used to find properties for different classes and construct different classes.
public class SerializationMethod {
public object ProcessByKind (string kindToUse, SerializationAction action, object objectToProcess) {
if (kindToUse == "FirstKind") {
if (action == SerializationAction.ToBytes) {
return new byte[1];
}
return new SomeClass(); // These would need to be your hard implementations. Not clean.
} else {
throw new NotImplementedException();
}
}
}
// This struct type defines the serialization method and is required for the interface implementation
public struct ByteSerialization
{
public string SerializationTypeName { get; private set; }
public ByteSerialization(string kindToUse) {
if (!SerializationKindList.Contains(kindToUse)) {
throw new ArgumentException();
}
SerializationTypeName = kindToUse;
}
public byte[] Deserialize(object objectToProcess) {
var serializationMethod = new SerializationMethod();
return (byte[])serializationMethod.ProcessByKind(this.SerializationTypeName, SerializationAction.ToBytes, objectToProcess);
}
public object Serialize(byte[] byteArrayToProcess) {
var serializationMethod = new SerializationMethod();
return serializationMethod.ProcessByKind(this.SerializationTypeName, SerializationAction.ToObject, byteArrayToProcess);
}
}
// Interface for any class that needs to use generic serialization
public interface IByteSerializable
{
ByteSerialization serializationType { get; }
}
// Creating extension methods for the interface to make the life easier
public static class IByteSerializableExtensions {
public static byte[] DeserializeObjectIntoBytes(this IByteSerializable objectToProcess) {
return objectToProcess.serializationType.Deserialize(objectToProcess);
}
public static void SerializeObjectFromBytes(this IByteSerializable objectToProcess, byte[] fromBytes) {
var someObjectData = objectToProcess.serializationType.Serialize(fromBytes);
}
}
// Abstract base class implementation with static readonly field.
// Only downside - there is no way to enforce the config of this field in the constructor from the interface.
// There also no way to make sure this field always gets set for other implementations of IByteSerializable
public abstract class SomeBaseClass : IByteSerializable
{
private static readonly ByteSerialization _serializationType = new ByteSerialization("FirstKind");
public ByteSerialization serializationType { get { return _serializationType; } }
}
public class SomeClass : SomeBaseClass {
}
// And here's how one would use it. You will need to create a new object of the class before serializing from bytes.
var someClass = new SomeClass();
var bytes = someClass.DeserializeObjectIntoBytes();
var someClass2 = new SomeClass();
var byteArray = new byte[1];
someClass2.SerializeObjectFromBytes(byteArray);
Use a generic interface and each implementation can close the generic and return the closed type. It is upto the implementation to decide what type to return.
public interface ICustomSerializable<T> where T : class
{
byte[] GetBytes();
T Deserialize(byte[]);
}
public class Foo : ICustomSerializable<Foo>
{
public byte[] GetBytes() {}
public Foo Deserialize(byte[]){}
}
public class Bar : ICustomSerializable<Bar>
{
public byte[] GetBytes() {}
public Bar Deserialize(byte[]){}
}
If you have classes which do serialization in a common way then:
public abstract class Something
{
public byte[] GetBytes() { //common code }
}
public class SomethingConcrete : Something, ICustomSerializable<SomethingConcrete>
{
public SomethingConcrete Deserialize(byte[]){}
}
I would like know if there is a way to have a ManagerClass that calls the constructors of different classes that share the same interface and inherit form the same base class. I can not call the specific derived class constructors themselves because the user can choose which objects to create at runtime, hence I have no knowledge of which derived objects to create until runtime.
For example:
public class managerClass : ISomeInterface
{
public BaseClass apply(someDataType) //(Notice return type is BaseClass)
{
run constructors of the derivedClasses or create essentially new derived objects, pass someDataType into the constructors
}
}
public class derivedClass : BaseClass, ISomeInterface
{
public void doSmthg(){manipulate data and store}
}
public class derivedClass2 : BaseClass, ISomeInterface
{
public void doSmthg(){manipulate data in another way and store}
}
Currently managerClass does not inherit from same BaseClass however if this somehow helps to allow me to do what I wish to do I am not against making this change.
You might take a look at the Activator class:
Type type = typeof(derivedClass2);
ISomeInterface instance = (ISomeInterface)Activator.Create(type);
There are some more overloads, like passing a classname instead of a type.
More info: http://msdn.microsoft.com/en-us/library/system.activator.aspx
Else you should look at Factory Design Pattern here http://msdn.microsoft.com/en-us/library/ee817667.aspx
What is your problem? Sure you can say:
public BaseClass Apply(SomeDataType someDataType)
{
BaseClass instance;
if (/* your condition */)
{
var dc = new DerivedClass();
// do stuff to/with dc
instance = dc;
}
else
{
var dc2 = new DerivedClass2();
// do stuff to/with dc2
instance = dc2;
}
// do common stuff to/with instance
return instance;
}
If all you want developers to have to do is create the class and the your manager will automatically be able to create instances of it, use Reflection to gather a list of the options to present to the user, and use Activator to create the instance when requested.
Dictionary<string, Type> DerivedOfferings{get;set;}
... //somewhere in the setup of your manager.
foreach (Type t in AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IEmtRequestProcessor)))))
{
DerivedOfferings.Add(t.Name, t);
}
//provide list of options to users.
IList<string> GetOfferingOptions(){
return DerivedOfferings.Keys.ToList();
}
...
public BaseClass GetOffering(string name){
return (BaseClass)Activator.CreateInstance(DerivedOfferings[type]);
}
If there is some logic that needs to be performed to decide which derived offering to create, you can provide an attribute for the developers to decorate their classes with which would hold information to perform the logic against.
public sealed class CreatureAttribute:Attribute
{
public int NumberOfLegs{get;set;}
public Color HairColor{get;set;}
public int NumberOfWings{get;set;}
public bool BreathsFire{get;set;}
}
[CreatureAttribute(NumberOfLegs=6, HairColor = Color.Magenta, NumberOfWings=0, BreathsFire=True)]
public class PurpleDragon: ICreature
{
...
}
Then retrieve these during enumeration and store these with the options.
List<CreatureCriteria> CreatureOptions{get;set;}
EnumerateOptions()
{
foreach (Type t in AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(ICreature)))))
{
foreach (CreatureAttribute creatureAttribute in
t.GetCustomAttributes(typeof (CreatureAttribute), false)
.Cast<CreatureAttribute>()
{
CreatureOptions.Add(
new CreatureCriteria{
Legs = creatureAttribute.NumberOfLegs,
HairColor = creatureAttribute.HairColor,
...
ConcreteType = t
}
);
}
}
}
And evaluate based on the criteria provided by the user..
ICreature CreateCreature(CreatureCriteria criteria){
CreatureCriteria bestMatch = CreatureOptions.FindBestMatch(criteria);
// perform logic comparing provided criteria against CreatureOptions to find best match.
return (ICreature)Activator.CreateInstance(bestMatch.ConcreteType);
}
I'm implementing a factory pattern that looks as follows.
public class FeedFactory
{
#region Singleton Pattern
//..
#endregion
private static Feed[] _factory = new Feed[(int)FeedType.Total];
public void RegisterFeed(FeedType feedType,Feed feed)
{
if (_factory[(int)feedType] == null)
{
_factory[(int)feedType] = feed;
}
else
{
// already registered
}
}
public Feed GetFeed(FeedType feedType)
{
return _factory[(int)feedType];
}
}
Here, Feed is an abstract class from which the different classes inherit. How can I register the different classes? Is it possible to do it from their constructor?
This is not a factory pattern. A factory will always have some constructor logic in it, at least one new. That's the idea of a factory: the caller doesn't have to worry about how objects are created. This is a singleton repository.
So first of all, instead of using an array, you should be having a type indexed dictionary.
private static Dictionary<Type, Feed> _singletons = new Dictionary<Type, Feed>();
After that, you don't need a register method. The dictionary should be filled automatically when you retrieve singletons.
Now I suppose your Feed class has a default constructor without arguments. In that case, you can implement a factory method directly from the abstract class Feed. We're going to use some generics here, because it allows you to control inheritance:
public abstract class Feed
{
public static T GetInstance<T>() where T:Feed, new()
{
T instance = new T();
// TODO: Implement here other initializing behaviour
return instance;
}
}
Now back to your singleton repository.
public class FeedSingletonRepository
{
private static readonly object _padlock = new object();
private static Dictionary<Type, Feed> _singletons = new Dictionary<Type, Feed>();
public static T GetFeed<T>() where T:Feed
{
lock(_padlock)
{
if (!_singletons.ContainsKey(typeof(T))
{
_singletons[typeof(T)] = Feed.GetInstance<T>();
}
return (T)_singletons[typeof(T)];
}
}
}
Note that I included a threadsafe behaviour which is a good thing to do when you work with singletons.
Now if you want to get the singleton for a given type inheriting from Feed (let's call it SpecializedFeedType), all you have to do is:
var singleton = FeedSingletonRepository.GetFeed<SpecializedFeedType>();
or
SpecializedFeedType singleton = FeedSingletonRepository.GetFeed();
which is the same line with a slightly different syntax.
Edit2: changed some syntax errors.
Just as a side note -- as a factory is intended to wrap creation, it's a curious choice that you're creating objects and registering them with the factory. Is this more an object repository than a factory, or is there more to the class than I'm seeing?
If it is an object repository, then you might also find some extra inspiration in other questions, like this one.
When you call the RegisterFeed method you need to pass a concrete instance of a Feed class. So it is the responsibility of the caller to provide the concrete implementation.
Just register the type of the classes you want to create, then use Activator.CreateInstance to create instances of that type.
It should work this way:
private static Type[] _factory = new Type[(int)FeedType.Total];
public void RegisterFeed(FeedType feedType, Type type)
{
...
_factory[(int)feedType] = type;
...
}
public Feed GetFeed(FeedType feedType)
{
return Activator.CreateInstance(_factory[(int)feedType]) as Feed;
}
You can call RegisterFeed like the following:
RegisterFeed(FeedType.SomethingSpecial, typeof(MyDerivedSpecialFeed));
class FeedFactory {
public IFeedFactory GetFeedFactory(string type) {
switch(type) {
case "1": return new Feed1(); break;
case "2": return new Feed2(); break;
}
}
}
Note all Feeds Must implement an IFeedFactory interface and implement the method necessary.
//From the client
FeedFactory ff1 = new FeedFactory();
IFeedFactory obj = ff1.GetFeedFactory("1");
obj.ExecuteMethod();
I have a wrapper generic class that intended to be used with a set of types. Those types are generated by a utility and are all derived from a base class ClientBase. While ClientBase has only a default constructor, all generated types have default constructor as well as a constructor takes a string as parameter. In the constructor of the wrapper class, I instantiate an instance of the type with the constructor that takes a string. Here is a sample code:
public class ClientBase
{ }
public class GenericProxy<T>
where T: ClientBase, new()
{
T _proxy;
public GenericProxy(string configName)
{
_proxy = new T(configName);
}
}
This code does not compile because type T is not guaranteed to have a constructor that takes a string. Is there a way to define a constrain on the generic class to enforce that the type T must have a constructor that take a string? If this is not possible, what are good alternatives to handle this kind of situation?
It's not possible. I'd like to see "static interfaces" to handle this, but don't expect them any time soon...
Alternatives:
Specify a delegate to act as a factory for T
Specify another interface to act as a factory for T
Specify an interface on T itself for initialization (and add a constraint so that T implements the interface)
The first two are really equivalent. Basically you'd change your proxy class to something like this:
public class GenericProxy<T>
where T: ClientBase, new()
{
string _configName;
T _proxy;
Func<string, T> _factory;
public GenericProxy(Func<string, T> factory, string configName)
{
_configName = configName;
_factory = factory;
RefreshProxy();
}
void RefreshProxy() // As an example; suppose we need to do this later too
{
_proxy = _factory(_configName);
}
}
(I assume you're going to want to create more instances later - otherwise you might as well pass an instance of T into the constructor.)
Unfortunately what you're trying to do isn't possible.
MSDN article on Type Constraints
This does not answer your actual question, constraining a method, but for completeness here's how you can do what you're asking at run time, using reflection:
private T Get<T>(string id)
{
var constructor = typeof(T).GetConstructor(new Type[] { typeof(X), typeof(Y) });
if (constructor == null) throw new InvalidOperationException("The type submitted, " + typeof(T).Name + ", does not support the expected constructor (X, Y).");
var data = GetData(id);
return (T)constructor.Invoke(new object[] { data.x, data.y });
}
As Jon notes, there is no inbuilt support for this - but as an aside you can create a typed delegate to the constructor (faster than reflection) using Expression. The code to do this can be found in MiscUtil (in MiscUtil.Linq.Extensions.TypeExt).
Here is a full working example based on #JonSkeet answer:
using System;
using System.Collections.Generic;
namespace GenericProxy
{
class Program
{
static void Main()
{
GenericProxy<ClientBase> proxy = new GenericProxy<ClientBase>(ClientBase.Factory, "cream");
Console.WriteLine(proxy.Proxy.ConfigName); // test to see it working
}
}
public class ClientBase
{
static public ClientBase Factory(string configName)
{
return new ClientBase(configName);
}
// default constructor as required by new() constraint
public ClientBase() { }
// constructor that takes arguments
public ClientBase(string configName) { _configName = configName; }
// simple method to demonstrate working example
public string ConfigName
{
get { return "ice " + _configName; }
}
private string _configName;
}
public class GenericProxy<T>
where T : ClientBase, new()
{
public GenericProxy(Func<string, T> factory, string configName)
{
Proxy = factory(configName);
}
public T Proxy { get; private set; }
}
}
Expect to see the following output: ice cream
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());
}