This time, I'm gonna create a math problems. I plan to have a dictionary where the key is Levels enum {Easy, Medium, Hard} and value should contain some configuration about how to create the problems.
For example:
BinaryProblemConfiguration
+ Bound1 : Bound<int>
+ Bound2 : Bound<int>
Bound has two properties: min and max.
Others types of problems don't need Bounds, but need other data.
So, I was thinking create a interface called IConfiguration.
public interface IConfiguration {}
And concrete Configurations should be:
public class BinaryProblemConfiguration : IConfiguration
{
public Bound Bound1 {get;set;}
public Bound Bound2 {get;set;}
}
public class AnotherProblemConfiguration : IConfiguration
{
// other stuff
}
The idea is to have a dictionary called ConfigurationLevels. Is this a good practice left the interface empty or means is wrong with my design?
The .NET Framework Design Guidelines calls this a "marker" interface and definitely says that it is a bad idea. They recommned using a custom Attribute instead.
Avoid using marker interfaces (interfaces with no members).
Custom attributes provide a way to mark a type. For more information
about custom attributes, see Writing Custom Attributes. Custom
attributes are preferred when you can defer checking for the attribute
until the code is executing. If your scenario requires compile-time
checking, you cannot comply with this guideline.
http://msdn.microsoft.com/en-us/library/ms229022.aspx
public sealed class ConfigurationAttribute : Attribute {
}
[ConfigurationAttribute]
public class AnotherProblemConfiguration : IConfiguration
{
// other stuff
}
Where would you use an instance of IConfiguration by itself? If there is a use case like this:
void Something(IConfiguration configuration) { ... }
Then yes, its fine. But with an empty interface, that's going to be an interesting use case. Offhand, the one that comes to mind is serializing objects, where you know that the object to be serialized via that method must be an IConfiguration, but you don't actually care about what IConfiguration looks like:
void SerializeConfiguration(IConfiguration configuration) { ... }
Now from a purely functional perspective, this would work just as well with Object, but I think it is a reasonable way of providing a compile-time mechanism for strongly suggesting that someone doesn't serialize anything but a configuration using this method.
Another common usage for these is marker interfaces, where you use reflection to find types that are 'marked' by implementing a common interface.
It can definitely be useful to have an interface which extends another interface but adds nothing to it. For example, one could easily imagine use cases for an IImmutableEnumerable<T> which inherits from IEnumerable<T>, but promises that the sequence of items it returns will never change for any reason. A routine which needs to have a list of items that isn't going to change could have overloads for IEnumerable<T> and IImmutableEnumerable<T>. The first overload could check whether supplied object instance implements IImmutableEnumerable<T> and, if not, produce a new immutable list by copying the items in the original; the second overload could simply use the passed-in list directly, since it would be known to implement IImmutableEnumerable<T>.
It's somewhat harder to imagine use cases for an interface which doesn't have any members at all. Such an interface could be used in constraints to allow a routine to accept various types which had no other common base type, but unfortunately class hierarchies which are complex enough to make such a thing conceptually useful make it very difficult to persist objects which meet such constraints.
Related
I'm developing a framework where a class inheriting from an abstract class of the framework needs to be able to specify the schema for the options it can accept when it is called to DoStuff().
I started out with an abstract GetOptionsSchema() method like this:
public abstract class Widget
{
public abstract OptionsSchema GetOptionsSchema();
public abstract void DoStuff(Options options);
}
Other developers would then extend on my framework by creating custom Widget types:
public abstract class FooWidget: Widget
{
public overide DoStuff(Options options)
{
//Do some FooWidget stuff
}
public overide OptionsSchema GetOptionsSchema()
{
//Return options for FooWidget
}
}
This works but requires the framework to create an instance of every Widget type to determine options schema they accept, even if it has no need to actually DoStuff() with any of these types.
Ultimately, I'd like to be able to determine the options schema for a specific Widget type directly from a System.Type. I would create a custom OptionsSchema attribute, but constructing these schemas is more complicated then would make sense to do in the constructor of an attribute. It needs to happen in a method.
I've seen other frameworks solve similar problems by creating a custom attribute that identifies a static method or property by name. For example the TestCaseSource attribute in NUnit.
Here's what this option might look like:
public abstract class Widget
{
public abstract void DoStuff(Options options);
}
[OptionsSchemaSource(nameof(GetOptionsSchema))]
public abstract class FooWidget: Widget
{
public overide DoStuff(Options options)
{
//Do some FooWidget stuff
}
public static OptionSchema GetOptionsSchema()
{
//Return options for FooWidget
}
}
I like how the OptionsSchemaSource attribute makes it possible to get the options schema directly from a System.Type, but this also seem much less discoverable to other developers creating custom Widget types.
With the abstract method another Widget developer knows they must override GetOptionSchema() because their code would not compile otherwise. With the OptionsSchemaSource attribute the best I could do would be to hope people read my documentation and have the framework throw an exception at run-time if it encounters a Widget with out an OptionsSchemaSource attribute.
Is there an alternative/better/recommended approach to this?
You pretty much already know everything of interest to judge what's the best approach.
As already mentioned, you cannot have static interfaces defined on your type, so there is no way you can ensure a new developer is enforced to add the attribute.
So, the two alternatives you identified are the only two I can think of.
Now, let's do a pros and cons and try to sharpen them.
Attribute
You can lessen the pain of ensuring devs put attributes on the classes with meaningful error messages. I would say that you should manage the discovery of the classes based exclusively on Attributes, not in inheritance.
If you manage everything with Attributes, you don't need to inherit from Widget.
This is a pro, because now everyone can inherit if it's desirable, and re-implement if it's preferred.
The con is that the implementation of discoverability will be more complex: you will need to use reflection at start up, get a MethodInfo, check that the method has the correct signature, give proper errors in case and invoke the method unboxing the result as needed.
Think about it: you would like a static method because you don't need to instantiate a single typed Widget instance, but actually instantiating a new Widget could very well be not a big deal.
Abstract class
Well, you enforce an inheritance chain over you developers, which could be ok, necessary or entirely optional (you judge), but you get a self documenting experience.
The apparent con is that at startup you need to instantiate a Widget for every derived type you discover, but that could very well be peanuts compared to assembly scanning and type checking and methodinfo discovery and method calls through reflection.
Ugly? Kind of. Inefficient? Not so much. And it's code that is invisible to your end user.
IMHO
I find quite a good tradeoff, when designing a framework, to put some "ugly" code inside the framework, if it means that every single implementation using the library is going to be even a little bit better.
All in all, if you're designing a library that you want to be flexible and discoverable, you should expect a developer to read at least a quick start guide. If they can read in 5 minutes a single bit of information (either "extend a base class" or "add a single or a couple attributes") and that single bit gives them an direction into discovering every aspect of widget registration, I would be ok: you can't really get much better than this.
My call: I would go the abstract class route with a smallish caveat. I really don't like having an enforced base class. So I would organize discovery at startup based on interface, IWidget, containing the GetOptionsSchema method and everything is needed to use the widget (which could be the DoStuff method, but could very well be something else). At startup you search for implementations of the interface which are not abstract, and you're good to go.
If, and only if, the only bit you really need in advance is a string or other similarly simple type, I would require an additional attribute.
[OptionsSchemaName("http://something")]
public class MyWidget : WidgetBase
{
public overide DoStuff(Options options)
{
//Do some FooWidget stuff
}
public static OptionSchema GetOptionsSchema()
{
//Return options for FooWidget
}
}
Then, your type discovery infrastructure can search for non-abstract IWidgets and throw a meaningful error right at startup like the type MyWidget is lacking an OptionsSchemaName attribute. Every implementation of IWidget must define one. See http://mydocs for information.
Bang! Nailed it!
It's not currently possible to enforce the attribute at compile time; that would've been ideal for your use case. It's also not possible to have an abstract static method, or have a static method specified in an interface; so there is no way to ensure the method is actually there at compile time, except by enforcing an instance method via abstract class or interface (which will require an instance of the type to access).
I'd go with the attribute idea - it's not unreasonable to expect developers to read documentation; even with overriding an abstract method, the developer would need to know how to construct an OptionSchema in the overridden method - back to documentation!
probably a no-brainer, but please take a look at the following classes / Interfaces:
public interface IChallenge
public interface IChallengeView<T> where T : IChallenge
{
T Challenge {get;set;}
}
public interface IChallengeHostView
{
IChallengeView<IChallenge> ChallengeView { get; set; }
}
public class AdditionChallenge : IChallenge {}
public class AdditionChallengeView: IChallengeView<AdditionChallenge> {}
The scenario is a didactic app for young children.
I intend to keep the application flexible by separating the host (which could be any graphical surrounding) from the challenge that is to be solved. That way I could use the same surroundings to host addition, multiplication,division...
Now, when I want to fill this with some life, I get a conversion issue:
HostView hostView = new HostView(); // implements IChallengeHostView
AdditionChallengeView challengeView = new AdditionChallengeView();
hostView.ChallengeView = challengeView;
This, of course, does not work. I see why it doesn't but I have no clue whatsoever how to get around this.
Any ideas?
UPDATE : I had decided to post as little code as possible before, but that brought me into the trouble of hiding one issue from you guys: The interface IChallengeView has a settable property (now visible in the code above), which makes covariance impossible to apply here - The generic type parameter can only be invariant in that case.
The answer given by rich.okelly is correct, but based on false assumptions (which, again, were based on the poor level of detail given by my description here).
I decided to make the code a little less implementation-type-adhesive, like so:
public interface IChallenge
public interface IChallengeView
{
IChallenge Challenge {get;set;}
}
public interface IChallengeHostView
{
IChallengeView ChallengeView { get; set; }
}
public class AdditionChallenge : IChallenge {}
public class AdditionChallengeView: IChallengeView {}
That means I have some more casting code in the AdditionChallengeView (and all other implementing classes), but it seems to me that this is the only viable way at the time.
If you're using c#4 (or above) you can take advantage of variance. Try declaring your IChallengeView<T> interface as covariant like so:
public interface IChallengeView<out T> where T : IChallenge {}
It is often useful to separate out portions of an interface that use a type parameter in covariant fashion and those which use one i contravariant fashion. This often requires the use of a "SetProperty" method rather than a read-write property (for whatever reason, if an interface inherits an interface which includes a read-only property Foo, and another which implements a write-only property Foo, the compiler will say any attempts at property access are "ambiguous" and won't allow foo to be read or written, notwithstanding the fact that read accesses can only refer to the read-only property and write accesses to the write-only property. Nonetheless, separating out contravariant and covariant aspects of an interface will often allow one to use variance in the cases where it would be helpful and make sense. Further, separating out the portions of an interface which read an object is often helpful anyway.
One minor note: I would suggest that when using an interface one use the following terms to have the indicated meanings:
An a "readable" foo interface should provide a means for reading the characteristics of an object, but should make no promise about whether the object might be writable using some other other means.
A "read-only" foo interface should not only provide a means for reading the characteristics of an object, but should also promise that one may expose a reference to any legitimate implementation without exposing a means of writing to the object. There is no promise, however, that there isn't some some other means by which the object might be modified.
An "immutable" foo interface should promise that any property which is observed to have a given value will always have that value.
If code needs to simply read out what's in an object, it can ask for an "IReadableFoo". If code is using an object reference for short-term encapsulation data which it wants to expose to other code, but isn't allowed to expose the object itself to anything that might modify it, it should wrap the object in a read-only wrapper unless it can safely expose the object directly (which would be indicated by the object implementing IReadOnlyFoo. If code wants to persist a reference as a means of persisting a snapshot of the data therein, it should make a copy of the object if there's any possibility that it might change, but shouldn't bother if the object will always be the same (indicated by IImmutableFoo).
Is it possible to set a constrain that all classes implementing an interface must have, for example, an empty constructor? Like the where T : new() constraint in generic ?
No - its not possible to place any such constraints on derived classes or implementors of a given interface.
Such constrains generally wouldn't be a particularly good idea / useful anyway, as generally when working with an interface you are normally working with instances of objects that implement that interface in which case the object has naturally already been created and such constraints are redundant. (The exception of course being generics, in which case you can use the new() constraint).
My guess is that you are attempting to create some sort of plugin system and wish to constrain implementations of your plugin interface to have some default constructor that you can use for instantiation... if this is the case then there are normally better alternatives that you can use, such as the MEF.
Can you elaborate more on why exactly you need this?
There are only four ways I can think of that you might be given a class at run-time which isn't known at compile-time. You might be given an instance of an object which implements an interface, and want to produce another one like it. That scenario would best be handled by having the interface include a NewSimilarInstance() method. You might have a method in some class which gets passed a generic type parameter which is constrained to your interface. In that scenario, the routine which accepts the generic parameter could have a new() constraint. Otherwise, you could be given a .net System.Type object or some other representation (such a string) for the type. In these latter two scenarios, no compile-time validation is going to be meaningful; doing anything with the types will require Reflection, and so you may as well use Reflection to see if they allow the creation of new instances.
No, there's nothing like that. It would be slightly odd, given that the normal use of interfaces is that the code using an interface shouldn't need to care about how it was instantiated - they shouldn't care about what the implementation class is, just that it implements the interface.
If you have some special use for this, I suggest you just write unit tests for it - if all the implementations will be in the same assembly, it should be pretty straightforward to do so, and will catch any errors at nearly the same time as compile-time...
I think you need to use a virtual class for that.
As Justin said not only you can't constrain constructor signatures using an interface but also it's not possible using an abstract class.
Maybe if you would explain why you need to place such a constrain we could find some other solutions for your problem
Inject a Factory into your generic class that can instantiate your interface, and drop the new() constraint.
Something like:
public interface IFactory<out T>
{
T CreateInstance();
}
public class GenericClass<T>
{
private readonly IFactory<T> _factory;
public GenericClass(IFactory<T> factory)
{
_factory = factory;
}
public DoSomething()
{
//...
T foo = _factory.CreateInstance();
//...
}
}
I'm making a game where each Actor is represented by a GameObjectController. Game Objects that can partake in combat implement ICombatant. How can I specify that arguments to a combat function must inherit from GameObjectController and implement ICombatant? Or does this indicate that my code is structured poorly?
public void ComputeAttackUpdate(ICombatant attacker, AttackType attackType, ICombatant victim)
In the above code, I want attacker and victim to inherit from GameObjectController and implement ICombatant. Is this syntactically possible?
I'd say it probably indicates you could restructure somehow, like, have a base Combatant class that attacker and victim inherit from, which inherits from GameObjectController and implements ICombatant.
however, you could do something like
ComputeAttackUpdate<T,U>(T attacker, AttackType attackType, U victim)
where T: ICombatant, GameObjectController
where U: ICombatant, GameObjectController
Although I probably wouldn't.
Presumably all ICombatants must also be GameObjectControllers? If so, you might want to make a new interface IGameObjectController and then declare:
interface IGameObjectController
{
// Interface here.
}
interface ICombatant : IGameObjectController
{
// Interface for combat stuff here.
}
class GameObjectController : IGameObjectController
{
// Implementation here.
}
class FooActor : GameObjectController, ICombatant
{
// Implementation for fighting here.
}
It is only syntactically possible if GameObjectController itself implements ICombatant; otherwise, I would say you have a design problem.
Interfaces are intended to define the operations available on some object; base classes identify what that object is. You can only pick one or the other. If accepting the ICombatant interface as an argument is not sufficient, it might indicate that ICombatant is defined too narrowly (i.e. doesn't support everything you need it to do).
I'd have to see the specifics of what you're trying to do with this object in order to go into much more depth.
What if you did this instead:
public class GameObjectControllerCombatant : GameObjectController, ICombatant
{
// ...
}
Then derive your combatant classes from this instead of directly from GameObjectController. It still feels to me like it's breaking encapsulation, and the awkwardness of the name is a strong indication that your combatant classes are violating the Single Responsibility Principle... but it would work.
Well, sort of. You can write a generic method:
public void ComputeAttackUpdate<T>(T attacker, AttackType type, T victim)
where T : GameObjectController, ICombatant
That means T has to satisfy both the constraints you need. It's pretty grim though - and if the attacker and victim could be different (somewhat unrelated) types, you'd have to make it generic in two type parameters instead.
However, I would personally try to go for a more natural solution. This isn't a situation I find myself in, certainly. If you need to regard an argument in two different ways, perhaps you actually want two different methods?
If you control all the classes in question, and if GameObjectController doesn't define any fields, the cleanest approach would be to define an IGameObjectController (whose properties and methods match those of GameObjectController) and an ICombatantGameObjectContoller (which derives from both IGameObjectController and ICombatant). Every class which is to be usable in situations that require both interfaces must be explicitly declared as implementing ICombatantGameObjectController, even though adding that declaration wouldn't require adding any extra code. If one does that, one can use parameters, fields, and variables of type ICombatantGameObjectController without difficulty.
If you can't set up your classes and interfaces as described above, the approach offered by Jon Skeet is a generally good one, but with a nasty caveat: to call a generic function like Mr. Skeet's ComputeAttackUpdate, the compiler has to be able to determine a single type which it knows is compatible with the type of the object being passed in and with all of the constraints. If there are descendants of GameObjectController which implement ICombatant but do not derive from a common base type which also implements GameObjectController, it may be difficult to store such objects in a field and later pass them to generic routines. There is a way, and if you need to I can explain it, but it's a bit tricky.
Consider the following:
public Something(IInterface concreteObjectOne, IInterface concreteObjectTwo)
{
this.concreteObjectOne = concreteObjectOne;
this.concreteObjectTwo = concreteObjectTwo;
}
How do I set set this type of binding up with Ninject? I'd try Googling the term, but as I'm not sure what this is called I can't, nor can I find anything on the Wiki about this.
Edit:
I believe this is called Convention Based Binding, as described here. However this documentation is for version 1.0 and 2.0 does not have the Only method. I'd like this to be achieved without attributes - using the convention of names or something similiar.
In addition to the use of "Only" method, the article suggests another solution by specifying different attributes for the injected objects.
Example:
public class ObjectOneAttribute : Attribute
{
}
public class ObjectTwoAttribute : Attribute
{
}
Then
public Something([ObjectOneAttribute] IInterface concreteObjectOne, [ObjectTwoAttribute] IInterface concreteObjectTwo)
{
this.concreteObjectOne = concreteObjectOne;
this.concreteObjectTwo = concreteObjectTwo;
}
And when you want to bind the interface to the correct concrete object, use the "WhereTargetHas" method:
Bind<IInterface>().To<YourConcreteTypeOne>().WhereTargetHas<ObjectOneAttribute>();
Bind<IInterface>().To<YourConcreteTypeTwo>().WhereTargetHas<ObjectTwoAttribute>();
Update: Solution without using attributes:
Use the method "When":
Bind<IInterface>().To<YourConcreteTypeOne>().When(r => r.Target.Name == "concreteObjectOne");
Bind<IInterface>().To<YourConcreteTypeTwo>().When(r => r.Target.Name == "concreteObjectTwo")
;
If I may be allowed to offer some general, instead of Ninject-specific, guidance on this, I would suggest that you reconsider your design slightly. The current constructor is vague because it offers no guidance about which implementation of IInterface that goes where - I realize that this is just a mock-up of your real API, and while the real API may offer more help to the human developer in the form of aptly named parameters, a machine like a DI Container cannot infer correct usage.
Many DI Containers offer some way to address such vagueness, for example by providing attributes you can use to associate names (metadata) with each dependency. AFAIR, Ninject has Inject attributes...
However, consider a couple of alternatives:
The first alternative is to encapsulate the two similar interface instances in an Parameter Object, like this:
public interface IParameterObject
{
IInterface ObjectOne { get; }
IInterface ObjectTwo { get; }
}
You can now change the constructor to take an instance of IParameterObject instead of the two interface instances themselves.
public Something(IParameterObject po)
{
this.concreteObjectOne = po.ObjectOne;
this.concreteObjectTwo = po.ObjectTwo;
}
This means that you can push configuration of IParameterObject to the Composition Root.
Another alternative to ponder is whether it makes sense to consider the case with two instances as just a special case of a more general design that takes any number of instances. This may not always be the case, but if it is, you can change the constructor to this:
public Something(IEnumerable<IInterface> objects)
I would personally prefer any of the above suggestions over anything that uses specific Ninject features, because it forces me to make the API more explicit in general, and thus more readable and maintainable.