I am trying to define code contracts for an interface using ContractClass
and ContractClassFor
. It works fine when everything is in the same assembly, but if I put the interface definition and its respective contract class in a different assembly then the concrete class implementation, it doesn't work anymore.
For example, this code works:
namespace DummyProject
{
[ContractClass(typeof(AccountContracts))]
public interface IAccount
{
void Deposit(double amount);
}
[ContractClassFor(typeof(IAccount))]
internal abstract class AccountContracts : IAccount
{
void IAccount.Deposit(double amount)
{
Contract.Requires(amount >= 0);
}
}
internal class Account : IAccount
{
public void Deposit(double amount)
{
Console.WriteLine(amount);
}
}
class Program
{
static void Main(string[] args)
{
Account account = new Account();
// Contract.Requires will be checked below
account.Deposit(-1);
}
}
}
Now, if I have a separate project with the following:
namespace SeparateAssembly
{
[ContractClass(typeof(SeparateAssemblyAccountContracts))]
public interface ISeparateAssemblyAccount
{
void Deposit(double amount);
}
[ContractClassFor(typeof(ISeparateAssemblyAccount))]
internal abstract class SeparateAssemblyAccountContracts
: ISeparateAssemblyAccount
{
void ISeparateAssemblyAccount.Deposit(double amount)
{
Contract.Requires(amount >= 0);
}
}
}
and then in the main project (different assembly from the above) if I write:
namespace DummyProject
{
internal class AccountFromSeparateAssembly
: ISeparateAssemblyAccount
{
public void Deposit(double amount)
{
Console.WriteLine(amount);
}
}
class Program
{
static void Main(string[] args)
{
ISeparateAssemblyAccount accountFromSeparateAssembly =
new AccountFromSeparateAssembly();
// Neither of the two statements below will work
// Contract.Requires will be ignored
accountFromSeparateAssembly.Deposit(-1);
((AccountFromSeparateAssembly)accountFromSeparateAssembly).Deposit(-1);
}
}
}
Then the Contract.Requires
is no longer checked in the Deposit
method.
Any ideas on this, please? Thanks a lot!
I managed to make it work by choosing Contract Reference Assembly
= Build
in the Code Contracts settings of the project containing ISeparateAssemblyAccount
and SeparateAssemblyAccountContracts
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With