Have to prove base class property invariant in all derived classes? - code-contracts

I have a base class in which I'm trying to use the Null Object pattern to provide a default logger implementation which can then be changed by IoC setter injection at a later stage.
public interface ILog
{
void Log(string message);
}
public class NoOpLogger: ILog
{
public void Log(string message)
{ }
}
public abstract class ClassWithLogger
{
private ILog _logger = new NoOpLogger();
protected ClassWithLogger()
{
Contract.Assert(Logger != null);
}
public ILog Logger
{
get { return _logger; }
set
{
Contract.Requires(value != null);
_logger = value;
Contract.Assert(Logger != null);
}
}
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(Logger != null);
}
}
public sealed class DerivedClass : ClassWithLogger
{
private readonly string _test;
public DerivedClass(string test)
{
Contract.Requires<ArgumentException>(!String.IsNullOrWhiteSpace(test));
_test = test;
// I get warning at end of ctor: "invariant unproven: Logger != null"
}
public void SomeMethod()
{
Logger.Log("blah");
}
}
As I indicate in the code, my issue is that I get a warning at the end of the derived class' constructor saying that the "Logger != null" object invariant from the base class has not been proven even though it's obvious nothing has changed the Logger property value and I also have contracts around the setter to ensure it can never be null anyway.
Is there any way to avoid having to reprove this fact in all derived classes, or is this just a limitation of the static analyser?
UPDATE: Problem has been fixed in latest version of CodeContracts. Also, I don't need the assert in the abstract base class constructor anymore (the line "Contract.Assert(Logger != null);")

I just tested your code as posted and it worked fine. Are you using the most recent version of Code Contracts (1.4.30707.2)?

Related

C# Class implementation with generics

Hi everyone I am studying C# but ran into some compiler errors:
I am getting the error: 'LinkedList' does not implement interface member 'IEnumerable.GetEnumerator()'
I think I did.
Below is the code:
using System;
using System.Collections.Generic;
namespace LinkedListGenericsExample
{
public class LinkedListNode<T>
{
//constructor
public LinkedListNode(T value)
{
//code here
}
//code here
}
//LinkedList class with generics. It inherit the IEnumerable class with
//generics. Should I use IEnumerable or IEnumerable<T>?
public class LinkedList<T>: IEnumerable<T>
{
//code here
}
public LinkedListNode<T> AddLast(T node)
{
//code here
}
public IEnumerator<T> GetEnumerator()
{
//code here
}
//here I think the GetEnumerator() method is implemented
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
//Trying this but not working. Also I am confused.
/*
IEnumerator IEnumerable<T>.GetEnumerator()
{
return GetEnumerator();
}
*/
//Main() below
}
I am using the Visual Studio Code to compile the code.
Error ecountered:
'LinkedList' does not implement interface member 'IEnumerable.GetEnumerator()'
Using the generic type 'IEnumerator' requires 1 type arguments
Using the generic type 'IEnumerable' requreis 1 type arguments
'IEnumerable' in explicit interface declaration is not an interface
Question:
1) Should I inherit the IEnumerable class or IEnumerable class with generic?
2) How can I implement the "IEnumerable.GetEnumerator()" It looks like the compiler is not recognized my GetEnumerator() implementation but I am not sure why....
Need some help here. Thank you!
Updating the complete code below. It works!!
using System;
using System.Collections; //using System.Collections instead
namespace LinkedListGenericsExample
{
//Linked list node class in Generics form
public class LinkedListNode<T>
{
//LinkedListNode constructor
public LinkedListNode(T value)
{
this.Value = value;
}
public T Value;
public LinkedListNode<T> Next {get; internal set;}
public LinkedListNode<T> Prev {get; internal set;}
}
public class LinkedList<T>: IEnumerable
{
public LinkedListNode<T> First {get; private set;}
public LinkedListNode<T> Last {get; private set;}
public LinkedListNode<T> AddLast(T node)
{
var newNode = new LinkedListNode<T>(node);
if (First == null)
{
First = newNode;
Last = First;
}
else
{
Last.Next = newNode;
Last = newNode;
}
return newNode;
}
public IEnumerator GetEnumerator()
{
LinkedListNode<T> current = First;
while(current != null)
{
yield return current.Value;
current = current.Next;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/*
IEnumerator IEnumerable<T>.GetEnumerator()
{
}
*/
}
class Program
{
static void Main(string[] args)
{
//Console.WriteLine("Hello World!");
var list2 = new LinkedList<int>();
var list3 = new LinkedList<String>();
list2.AddLast(1);
list2.AddLast(3);
list2.AddLast(5);
//Go throuhg entire list of numbers
foreach(int i in list2)
{
Console.WriteLine(i);
}
Console.WriteLine();
list3.AddLast("2");
list3.AddLast("four");
list3.AddLast("foo");
//Go through entire list of strings
foreach(string s in list3)
{
Console.WriteLine(s);
}
}
}
}
Regarding your two questions, here are 2 cents.
1. I would suggest you implement the generic version. This would ensure type-safety and other benefits. You can read more on advantages of generics in this link. . Since you are learning C#, it would be a good idea to read about it.
Your implementation looks good.Please add reference to System.Collections namespace to your code for fixing the compile errors.
using System.Collections;

How is IClock resolved with SystemClock in this example?

I am trying to learn IOC principle from this screencast
Inversion of Control from First Principles - Top Gear Style
I tried do as per screencast but i get an error while AutomaticFactory try create an object of AutoCue. AutoCue class has contructor which takes IClock and not SystemClock. But my question is , in screencast IClock is resolved with SystemClock while inside AutomaticFactory .But in my code , IClock does not get resolved . Am i missing something ?
class Program
{
static void Main(string[] args)
{
//var clarkson = new Clarkson(new AutoCue(new SystemClock()), new Megaphone());
//var clarkson = ClarksonFactory.SpawnOne();
var clarkson = (Clarkson)AutomaticFactory.GetOne(typeof(Clarkson));
clarkson.SaySomething();
Console.Read();
}
}
public class AutomaticFactory
{
public static object GetOne(Type type)
{
var constructor = type.GetConstructors().Single();
var parameters = constructor.GetParameters();
if (!parameters.Any()) return Activator.CreateInstance(type);
var args = new List<object>();
foreach(var parameter in parameters)
{
var arg = GetOne(parameter.ParameterType);
args.Add(arg);
}
var result = Activator.CreateInstance(type, args.ToArray());
return result;
}
}
public class Clarkson
{
private readonly AutoCue _autocue;
private readonly Megaphone _megaphone;
public Clarkson(AutoCue autocue,Megaphone megaphone)
{
_autocue = autocue;
_megaphone =megaphone;
}
public void SaySomething()
{
var message = _autocue.GetCue();
_megaphone.Shout(message);
}
}
public class Megaphone
{
public void Shout(string message)
{
Console.WriteLine(message);
}
}
public interface IClock
{
DateTime Now { get; }
}
public class SystemClock : IClock
{
public DateTime Now { get { return DateTime.Now; } }
}
public class AutoCue
{
private readonly IClock _clock;
public AutoCue(IClock clock)
{
_clock = clock;
}
public string GetCue()
{
DateTime now = _clock.Now;
if (now.DayOfWeek == DayOfWeek.Sunday)
{
return "Its a sunday!";
}
else
{
return "I have to work!";
}
}
}
What you basically implemented is a small IoC container that is able to auto-wire object graphs. But your implementation is only able to create object graphs of concrete objects. This makes your code violate the Dependency Inversion Principle.
What's missing from the implementation is some sort of Register method that tells your AutomaticFactory that when confronted with an abstraction, it should resolve the registered implementation. That could look as follows:
private static readonly Dictionary<Type, Type> registrations =
new Dictionary<Type, Type>();
public static void Register<TService, TImplementation>()
where TImplementation : class, TService
where TService : class
{
registrations.Add(typeof(TService), typeof(TImplementation));
}
No you will have to do an adjustment to the GetOne method as well. You can add the following code at the start of the GetOne method:
if (registrations.ContainsKey(type))
{
type = registrations[type];
}
That will ensure that if the supplied type is registered in the AutomaticFactory as TService, the mapped TImplementation will be used and the factory will continue using this implementation as the type to build up.
This does mean however that you now have to explicitly register the mapping between IClock and SystemClock (which is a quite natural thing to do if you're working with an IoC container). You must make this mapping before the first instance is resolved from the AutomaticFactory. So you should add the following line to to the beginning of the Main method:
AutomaticFactory.Register<IClock, SystemClock>();

NServiceBus Configuration with Custom Container

I am trying to re-use the service registrations in an assembly that I use through a few services in my solution. I follow the example listed from the NServiceBus website to implement the solution. When following that, unless I add the IWantCustomInitialization interface, my Init method (and IoC container implementation) appears not to function. When I have that interface implemented, I get exceptions (listed in SO questions here and here). I can't seem to get it to work that there are no exceptions AND the dependencies in my MessageHandler are being populated properly. Here is my current EndpointConfig implementation.
[EndpointSLA("00:00:30")]
public class EndpointConfig : IConfigureThisEndpoint, AsA_Server, UsingTransport<Msmq>, INeedInitialization {
public void Init() {
Configure.With().ObjectBuilderAdapter();
}
}
public class ObjectBuilderAdapter : IContainer {
readonly IDependencyInjector injector;
public ObjectBuilderAdapter(IDependencyInjectionBuilder dependencyInjectionBuilder) {
injector = dependencyInjectionBuilder.Create(); //This method does all the common service registrations that I am trying to re-use
//injector.RegisterType<ExtractIncomingPrincipal, PrincipalExtractor>();
}
public void Dispose() {
injector.Dispose();
}
public object Build(Type typeToBuild) {
return injector.Resolve(typeToBuild);
}
public IContainer BuildChildContainer() {
return new ObjectBuilderAdapter(new DependencyInjectorBuilder());
}
public IEnumerable<object> BuildAll(Type typeToBuild) {
return injector.ResolveAll(typeToBuild);
}
public void Configure(Type component, DependencyLifecycle dependencyLifecycle) {
injector.RegisterType(component);
}
public void Configure<T>(Func<T> component, DependencyLifecycle dependencyLifecycle) {
injector.RegisterType(component);
}
public void ConfigureProperty(Type component, string property, object value) {
if (injector is AutofacDependencyInjector) {
((AutofacDependencyInjector)injector).ConfigureProperty(component, property, value);
} else {
Debug.WriteLine("Configuring {0} for property {1} but we don't handle this scenario.", component.Name, property);
}
}
public void RegisterSingleton(Type lookupType, object instance) {
injector.RegisterInstance(lookupType, instance);
}
public bool HasComponent(Type componentType) {
return injector.IsRegistered(componentType);
}
public void Release(object instance) { }
}
public static class Extensions {
public static Configure ObjectBuilderAdapter(this Configure config) {
ConfigureCommon.With(config, new ObjectBuilderAdapter(new DependencyInjectorBuilder()));
return config;
}
}
Note: When I use the INeedInitialization interface, I get the ComponentNotRegisteredException when it's looking for IStartableBus.
When you are trying to swap the built in container, then you need to implement IWantCustomInitialization in the same class that implements IConfigureThisEndpoint.
You can use your own container and register all your types in there and tell NSB to use that container.
For example:
public class EndpointConfig : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
{
public void Init()
{
var container = new ContainerBuilder().Build();
Configure.With()
.AutofacBuilder(container);
}
}

Trying Decorator Design Pattern, what's wrong with this code?

I have this code that explains the decorator pattern:
public abstract class IBeverage {
protected string description = "Unknown beverage";
public virtual string getDescription() {
return description;
}
}
public abstract class CondimentDecorator : IBeverage {
public abstract string getDescription();
}
public class Espresso : IBeverage {
public Espresso() {
description = "Espresso";
}
}
public class Mocha : CondimentDecorator {
IBeverage beverage;
public Mocha(IBeverage beverage) {
this.beverage = beverage;
}
public override string getDescription() {
return beverage.getDescription() + ", Mocha";
}
}
I should use it like:
static void Main(string[] args) {
IBeverage b = new Espresso();
Console.WriteLine(b.getDescription());
b = new Mocha(b);
Console.WriteLine(b.getDescription());
Console.ReadKey();
}
When I create the beverage (Beverage b = new Espresso();) _description is updated to "Espresso", when I decorate b with Mocha (b = new Mocha(b)), then _description takes the original value "Unknown Beverage". It should be "Espresso, Mocha". What's wrong?
This code was originally written in Java (the book was written with Java), but I translated it into C#. I guess Java works a little different from C#.
Because GetDescription() is not virtual.
public virtual string GetDescription() { ... }
virtual is the companion keyword to override, it's what allows subclasses to override methods. This is a key difference in C# from Java. In Java all methods are implicitly virtual.
You've actually got a few issues here (perhaps differing designs from Java). Even after sorting all of the naming issues, you will not get what you expect.
public abstract class CondimentDecorator : IBeverage {
public abstract string GetDescription();
}
The CondimentDecorator class will actually hide the IBeverage version GetDescription() method (you technically should use public new abstract string GetDescription();.
You are classifying the Mocha class as an IBeverage by assigning it to the b variable (which you earlier defined as an IBeverage via IBeverage b = new Espresso(), the IBeverage version of the GetDescription() method is what actually fires (totally ignoring the Mocha override of the CondimentDecorator GetDescription() method)
You can see this if you step through the code. Try using
CondimentDecorator m = new Mocha(b);
Console.WriteLine(m.GetDescription());
and you will get what you expect.
However, this kind of defeats the purpose of using a decorator in my opinion. A better option would be to change the design a bit and get rid of the CondimentDecorator. It is not providing anything other than confusion and unexpected behaviour. Instead try this:
This is your only needed abstract Beverage class:
public abstract class Beverage
{
// c# convention is to use properties instead of public fields.
// In this case I've used a private readonly backing field.
private readonly string _description = "Unknown Beverage";
protected string Description
{
get { return _description; }
set { _description = value; }
}
// Make this method virtual so you can override it, but if you
// choose not to, this is the default behaviour.
public virtual string GetDescription()
{
return Description;
}
}
This is a standard beverage class (can be decorated):
public class Espresso : Beverage
{
public Espresso()
{
// Setting the Beverage class Description property.
// You can use base.Description if you prefer to be explicit
Description = "Espresso";
}
}
This is a Beverage class that decorates another Beverage class:
public class Mocha : Beverage
{
// store an instance of the Beverage class to be decorated
private readonly Beverage _beverage;
// Beverage instance to be decorated is passed in via constructor
public Mocha(Beverage beverage)
{
_beverage = beverage;
}
// Override Beverage.GetDescription
public override string GetDescription()
{
// Calls decorated Beverage's GetDescription and appends to it.
return _beverage.GetDescription() + ", Mocha";
}
}
And now to get the behaviour you expect, you can run the same code as above:
static void Main(string[] args)
{
Beverage b = new Espresso();
Console.WriteLine(b.getDescription()); // "Espresso"
b = new Mocha(b);
Console.WriteLine(b.getDescription()); // "Espresso, Mocha"
Console.ReadKey();
}
As a side note. You can avoid using Console.ReadKey(); when debugging by using Ctrl + F5 This will automatically put in "Press any key to continue..." for you.
UPDATE
Since you want to include the CondimentDecorator class (as mentioned in your comment), you can create the following class:
public abstract class CondimentDecorator : Beverage
{
private readonly Beverage _beverage;
protected Beverage Bevy
{
get { return _beverage; }
}
protected CondimentDecorator(Beverage beverage)
{
_beverage = beverage;
}
}
Then you would change your Mocha class to the following:
// override CondimentDecorator instead of Beverage
public class Mocha : CondimentDecorator
{
// Pass the Beverage to be decorated to the base constructor
// (CondimentDecorator)
public Mocha(Beverage beverage)
: base(beverage)
{
// nothing needed in this constructor
}
public override string GetDescription()
{
// Now access the CondimentDecorator's Beverage property
// (which I called Bevy to differentiate it)
return Bevy.GetDescription() + ", Mocha";
}
}

Enum-Like object which contains properties

I am trying to figure out a way to have a class full of static objects which each can have a variety of static properties.
I want to be able to pass these properties around and even set them as static properties of other object and I also want to be able to switch through the objects.
Here is an example illustrating what I mean:
Creating and Sending a Message
class Program
{
static void Main(string[] args)
{
MarketOrder Order = new MarketOrder("DELL", MessageProperties.SecurityType.Equity, MessageProperties.ExchangeDestination.ARCA.PostOnly);
SendOrder(Order);
Console.ReadLine();
}
public static void SendOrder(MarketOrder Order)
{
switch (Order.SecurityType)
{
case MessageProperties.SecurityType.Equity:
// Equity sending logic here
break;
case MessageProperties.SecurityType.Option:
// Option sending logic here
break;
case MessageProperties.SecurityType.Future:
// Future sending logic here
break;
}
}
}
This does not want to compile because it won't let me switch the Order.SecurityType object.
MarketOrder Class
public class MarketOrder
{
public readonly string Symbol;
public readonly MessageProperties.SecurityType SecurityType;
public readonly MessageProperties.ExchangeDestination ExchangeDestination;
public MarketOrder(string Symbol, MessageProperties.SecurityType SecurityType, MessageProperties.ExchangeDestination ExchangeDestination)
{
this.Symbol = Symbol;
this.SecurityType = SecurityType;
this.ExchangeDestination = ExchangeDestination;
}
}
MessageProperties Class
public abstract class MessageProperties
{
public class ExchangeDestination
{
public readonly string Value;
public readonly double ExchangeFee;
public ExchangeDestination(string Value, double ExchangeFeed)
{
this.Value = Value;
this.ExchangeFee = ExchangeFee;
}
public abstract class ARCA
{
public static ExchangeDestination Only = new ExchangeDestination("ARCA.ONLY", 0.01);
public static ExchangeDestination PostOnly = new ExchangeDestination("ARCA.ONLYP", 0.02);
}
public abstract class NYSE
{
public static ExchangeDestination Only = new ExchangeDestination("NYSE.ONLY", 0.01);
public static ExchangeDestination PostOnly = new ExchangeDestination("NYSE.ONLYP", 0.03);
}
}
public class SecurityType
{
public readonly string Value;
public SecurityType(string Value)
{
this.Value = Value;
}
public static SecurityType Equity = new SecurityType("EQ");
public static SecurityType Option = new SecurityType("OPT");
public static SecurityType Future = new SecurityType("FUT");
}
}
Enums work perfectly for what I am trying to do except it is hard to have multiple properties of an enum value. I considered using Attributes on Enums to set the properties but getting those vs. getting static properties of objects is substantially slower and my application is extremely speed/latency sensitive.
Is there perhaps a better way of accomplishing what I am trying to do?
Thanks in advance for your help!
William

Resources