I'm working with Microsoft Code Contracts for a little while now and today I stumbled upon an awkward case. My question is - is there an elegant way to resolve this situation?
Let's assume I've got a simple trait interface for a repository which looks like this:
[ContractClass(typeof(CanAddContract)]
public interface ICanAdd {
void Add(object entity);
}
The contract for this, as denoted in the attribute, looks like this:
[ContractClassFor(typeof(ICanAdd))]
internal abstract class CanAddContract {
public void Add(object entity) {
Contract.Requires(object != null); // guard against null argument
}
}
So, now we've got a similar trait for entity deletion
[ContractClass(typeof(CanDeleteContract))]
public interface ICanDelete {
void Delete(object entity);
}
...and the contract...
[ContractClassFor(typeof(ICanDelete))]
internal abstract class CanDeleteContract {
public void Delete(object entity) {
Contract.Requires(entity != null); // guard against null argument
}
}
Nothing wrong about that. But since the interfaces denote repository traits, they are being used to compose a repository interface:
public interface IEntityStore : ICanAdd, ICanDelete {
void SomeOtherMethodThatNeedsAContract();
}
Now what? When I want to create a contract class for this interface, I have to reimplement both contract classes stated above again, since multi-inheritance isn't allowed in C#. This leaves me in a situation where I have to duplicate code for a CONTRACT. Think about that - this seems wrong to me in every possible case.
What could I do about it?
The CodeContracts compile-time rewriter will automatically discover and use the contracts for all base interfaces.
For your specific example (note how you do NOT need to repeat any of the base interfaces' contracts, and yet they still work):