Created
January 16, 2014 22:28
-
-
Save taeber/8464747 to your computer and use it in GitHub Desktop.
Demo of an OptionalDependency helper class which should prevent modifying an optional dependency (see Property Injection pattern) in the middle of a class's lifetime.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using Microsoft.VisualStudio.TestTools.UnitTesting; | |
sealed class OptionalDependency<T> where T : class | |
{ | |
private OptionalDependency() { } | |
private OptionalDependency(T defaultDependency) | |
{ | |
if (defaultDependency == null) | |
{ | |
throw new ArgumentNullException("defaultDependency"); | |
} | |
_value = defaultDependency; | |
_accessed = false; | |
} | |
public static implicit operator OptionalDependency<T>(T t) | |
{ | |
return new OptionalDependency<T>(t); | |
} | |
private bool _accessed; | |
private T _value; | |
public T Value | |
{ | |
get | |
{ | |
_accessed = true; | |
return _value; | |
} | |
set | |
{ | |
if (_accessed) | |
{ | |
throw new NotSupportedException("Dependency has already been accessed and cannot be changed."); | |
} | |
if (value == null) | |
{ | |
throw new ArgumentNullException(); | |
} | |
_value = value; | |
} | |
} | |
} | |
class SomeClass | |
{ | |
private readonly OptionalDependency<ISomeInterface> _dependency; | |
public ISomeInterface Dependency | |
{ | |
get { return _dependency.Value; } | |
set { _dependency.Value = value; } | |
} | |
public SomeClass() | |
{ | |
_dependency = new DefaultImplementation(); | |
} | |
} | |
interface ISomeInterface | |
{ | |
bool Operation(); | |
} | |
class DefaultImplementation : ISomeInterface | |
{ | |
public bool Operation() | |
{ | |
return true; | |
} | |
} | |
class OtherImplementation : ISomeInterface | |
{ | |
public bool Operation() | |
{ | |
return false; | |
} | |
} | |
[TestClass] | |
public class OptionalDependencyTests | |
{ | |
[TestMethod] | |
public void CanSetUsingPropertyInitializerBar() | |
{ | |
var b = new SomeClass { Dependency = new OtherImplementation() }; | |
b.Dependency = new OtherImplementation(); | |
Assert.IsFalse(b.Dependency.Operation()); | |
try | |
{ | |
b.Dependency = new DefaultImplementation(); | |
Assert.Fail("Shold have thrown exception"); | |
} | |
catch (NotSupportedException) | |
{ | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment