I have a couple of environment variables that are used as part of creating defaults for config options. Basically if the config options property in question is null then use the value from the specified environment variable.
I want to test the options objects correctly use the environment variable when null, so initially thought I'd just set the specified environment variable. However, this is an environment variable that will actually be used on the environment and therefore I don't really want to be messing with it. Is there a way I can wrap environment variables using an interface or something so I can mock the SetEnironmentVariable() method or something similar?
In terms of code my options objects look something like this:
public sealed record MyOptions
{
public string SomeProperty { get; set; }
public MyOptions()
{
var defaultVal = Environment.GetEnvironmentVariable("MY_VARIABLE");
SomeProperty = SomeProperty ?? defaultVal;
}
}
So if the SomeProperty hasn't been set via config, it will use the default value from the specified environment variable. I was thinking perhaps an EnvironmentVariableService, that retrieves all environment variables and puts them in a ConcurrentDictionary, and that's used in the place of the Environment.
Your question contains the answer🙂.
It is quite normal to wrap common .NET concrete implementations such as a timer, DateTime.Now, and utility class such as Environment and then inject that wrapper into the places that would normally use the concrete implementation.
Your case is a little unique in that you need access inside a sealed record. I would recommend you create a singleton of the service in that case. Ideally you avoid this approach.
The wrapper acts as an abstraction as mentioned in the comments to your question, and allows for the implementation to be swapped out in circumstances such as unit tests.
I happen to have implemented such a thing as I had this need as well. Here's the code.
public interface IEnvironmentService
{
string? GetEnvironmentVariable(string name);
void SetEnvironmentVariable(string name, string? value);
}
public class MockEnvironmentService : IEnvironmentService
{
public string? GetEnvironmentVariable(string name)
{
var found = !_dictionary.TryGetValue(name, out var value);
if (!found) value = null;
_actions.Add(new GetAction(name, value, found));
return value;
}
public void SetEnvironmentVariable(string name, string? value)
{
_dictionary[name] = value;
_actions.Add(new SetAction(name, value));
}
public IReadOnlyCollection<Action> AllActions => _actions.ToArray();
public IReadOnlyCollection<GetAction> GetActions => _actions.OfType<GetAction>().ToArray();
public IReadOnlyCollection<SetAction> SetActions => _actions.OfType<SetAction>().ToArray();
// see note after the code
private readonly Dictionary<string, string?> _dictionary = new(StringComparer.InvariantCultureIgnoreCase);
private readonly List<Action> _actions = new();
}
public class EnvironmentVariableService : IEnvironmentService
{
public string? GetEnvironmentVariable(string name) => Environment.GetEnvironmentVariable(name);
public void SetEnvironmentVariable(string name, string? value) => Environment.SetEnvironmentVariable(name, value);
}
public record Action(string Name, string? Value);
public record SetAction(string Name, string? Value) : Action(Name, Value);
public record GetAction(string Name, string? Value, bool WasFound) : Action(Name, Value);
At the beginning of your tests, if you need to preset/seed some environment variables to test read-side code, you can call MockEnvironmentService.SetEnvironmentVariable().
The implementation above uses a case insensitive dictionary for the keys, but whether names are case sensitive really depends on the OS.
Finally, the mock records the get/set calls in the order they occur, and you can use the properties in your assertions.
Related
One of our projects makes use of key-value pairs where certain runtime parameters - that do not change per instance of the program - determine the value gotten. For example:
Program run in test mode with the parameter "Municipal":
Key: "testMunicipalDirectory"
Value: "C:\Foo\Bar\"
Program run with the parameter "State":
Key: "StateDirectory"
Value: "C:\Bar\Baz\"
To make it slightly more complicated, if there is no matching key for, say "testMunicipalImagesDirectory", there is a fallback of "defaultImagesDirectory":
Key: "testMunicipalImagesDirectory" ?? "defaultImagesDirectory"
Value: "C:\Foo\Bar\Images" ?? "C:\Images"
Currently, there's a lot of code duplication/inefficiencies, and room for error. Every time one of these is referenced there's string concatenation and null-coalescing and other stuff going on.
It seems like this would benefit from a single-instance object that is passed certain parameters on initialization (test or not, "State" or "Municipal", etc), that will return the correct values for each different property the keys represent.
Many answers I found to questions asking how to use the singleton design pattern with parameters basically boil down to "if it uses parameters, you probably do not want a singleton". In my case, it is invalid to attempt to initialize the object with different values, and an exception should be thrown if this happens.
This is how I would accomplish this goal (pseudo-C#) (lazy-loading is not a requirement but is used here):
public sealed class Helper
{
// how can we enforce that Init has been called?
private static readonly Lazy<Helper> lazyLoader = new Lazy<Helper>(() => new Helper(name, test));
public static Helper Instance { get { return lazyLoader.Value; } }
public static void Init(string name, bool test)
{
// if it has already been initalized
throw new InvalidOperationException("This has already been initalized.");
// else initalize it
}
private string Name { get; set; }
private bool Test { get; set; }
private Helper(string name, bool test) { } // assign to properties, any other ctor logic
public string Directory
{ get { return ValueGetter.Get((this.Test ? "test" : "") + this.Name + "Directory"); } }
}
public static class ValueGetter
{
public static string Get(string key, string fallbackKey)
{
if (Keys.Any(k => k == key))
return Keys[key].Value;
else
return Keys[fallbackKey].Value;
}
}
But as you can see, there are questions remaining. How can it enforce calling Init before using the Instance, but not require those parameters to be passed every time Instance is accessed?
Is this the correct direction to go, or is there a better design pattern to use?
If I am to write unit tests for reading/writing/creating registry entries or files, my understanding is that I should not be using real registry and file system but should mock them in a light weight manner.
What mocking framework would you recommend for mocking these in C# desktop/WPF style apps?
What would be a good introductory reading into this topic?
OK, here's an example.
Given these classes:
public interface IRegistryActions
{
bool WriteValue(string key, string value);
}
public class RegistryActions : IRegistryActions
{
public bool WriteValue(string key, string value)
{
// pseudocode
// var key = Registry.OpenKey(key);
// Registry.WriteValue(key, value);
}
}
And this class that uses them: the class which will perform the actions is passed to the constructor in this example, but could as easily be a property. This means that whenever you want to actually use the class in your actual code, you can explicitly pass a class that implements IRegistryActions as a parameter - e.g. var exampleClass = new ExampleClass(new RegistryActions()); - or alternatively default to the actual implementation if passed null, i.e. this.registryActions = registryActions ?? new RegistryActions();
public class ExampleClass
{
private IRegistryActions registryActions;
public ExampleClass(IRegistryActions registryActions)
{
this.registryActions = registryActions;
}
public bool WriteValue(string key, string value)
{
return registryActions.WriteValue(key, value);
}
}
So in your unit test you want to verify that the call is made with the right parameters. How exactly you do this depends on what mocking framework you use, which is generally either a matter of personal choice or you use what's already used.
[Test]
public void Test_Registry_Writes_Correct_Values()
{
string key = "foo";
string value = "bar";
// you would normally do this next bit in the Setup method or test class constructor rather than in the test itself
Mock<IRegistryActions> mock = MockFramework.CreateMock<IRegistryActions>();
var classToTest = new ExampleClass(mock); // some frameworks make you pass mock.Object
// Tell the mock what you expect to happen to it
mock.Expect(m => m.WriteValue(key, value));
// Call the action:
classToTest.WriteValue(key, value);
// Check the mock to make sure it happened:
mock.VerifyAll();
}
In this you're asserting that your class has called the correct method on the interface, and passed the correct values.
New to C#, and I understand that encapsulation is just a way of "protecting data". But I am still unclear. I thought that the point of get and set accessors were to add tests within those methods to check to see if parameters meet certain criteria, before allowing an external function to get and set anything, like this:
private string myName;
public string MyName;// this is a property, speical to c#, which sets the backing field.
private string myName = "mary";// the backing field.
public string MyName // this is a property, which sets/gets the backing field.
{
get
{
return myName;
}
set
{
if (value != "Silly Woman"){
myName = value;
}
}
}
But I've been seeing code in c# which just looks like this:
public string MyName { get; set; }
Why would you just have a get and set with nothing in there, - isn't that the same as just declaring your private backing field public? If you can just get and set it from outside, why wouldn't you just do it directly?
Indeed, creating an auto-property as follows:
public string Name { get; set; }
is identical to building a property backed by a field:
private string _name;
public string Name {
get { return _name; }
set { _name = value; }
}
The point of these properties is not to hide data. As you observed, they don't do this. Instead, these properties can do other stuff instead of just working with a field:
public string Name {
get { return _name; }
set { if (value == null) throw new Exception("GTFO!"); _name = value; }
}
Another thing is, you can make properties virtual:
public virtual string Name { get; set; }
which, if overridden, can provide different results and behaviours in a derived class.
By using public string MyName { get; set; }, you leave an ability to change its logic later without the need to recompile/change other code that uses your property.
For example, if you are making a library and v1 uses a field and v2 uses a property, applications that work with v1 will not work with v2 without recompilation (and, potentially, code changes if they are written in some .NET language that has different syntax for accessing fields).
Another important difference is in serialization scenarios -- a lot of them do not support fields. Also any interface that requires a property can not be implemented without using one, but depending on interface it may not be required to do any additional checks/logic in it.
It makes it easier to add logic later. If you have a class that has a public field that you want to change to a property, you have to recompile everything that uses your class. That's a key point that I didn't understand initially.
If you have a class:
public class MyClass
{
public string MyString;
}
You could access the value like this:
var myClass = new MyClass();
string s = myClass.MyString;
Now change that to a property:
public class MyClass
{
public string MyString { get; set; }
}
How is it accessed? The exact same way:
var myClass = new MyClass();
string s = myClass.MyString;
So no big deal, right? Well, actually....
Properties are actually compiled into getter and setter methods:
get_MyString() and set_MyString(string value)
So the two methods do produce different compiled code. Now if all your code that uses this class is in the same project, is not as big a deal, because it will all be compiled together. But if you have an API library that you've distributed, it can be a much bigger deal to update.
Because it is easier to change the Code if you want to add the checks/tests later on.
Especially if you have many inheritance and many classes in your code it is very hard to change the implementation from a public variable to a public Property.
Moreover you can add to the get and set within the property different attributes, e.g. if you are using reflection. The get and set of the property are internally different methods. If you have just a public variable /field it is not possible to added different properties to the different access ways.
Yeah, but you can easily change it to:
public string MyName { get; private set; }
Plus, properties are used in other scenarios, like DataContracts and Serialization... so, this is a nice feature... (Mostly, syntactic sugar. I think) EDIT: I take that back.. you can apply virtual to it, so it's not the same
I have some extension methods which could be used like this:
MyType myObject;
string displayName = myObject.GetDisplayName(x => x.Property);
The problem here is that it needs an instance, even if the extension method only needs the type MyType. So if there is no instance, it needs to be called like this:
string displayName = BlahBlahUtility.GetDisplayName((MyTpe x) => x.Property);
Which is not so nice anymore.
Is there a way to write better syntax for such cases?
What I actually want to do is this (pseudo language):
string displayName = MyType.Property.GetDisplayName()
Which of course does not work with C#.
But what about something like this:
string displayName = ((MyType x) => x.Property).GetDisplayName();
This is also not possible (after a lambda, a dot is not accepted).
Any ideas?
Edit:
My "favorite syntax" MyType.Property.GetDisplayName() seems to be misleading. I don't talk about static properties here. I know that this syntax won't be possible. I just tried to show in pseudo language, what information is necessary. This would be ideal, every additional stuff is just syntactical overhead. Any working syntax that is close to this would be great.
I don't want to write a certain extension method. I want an easy, readable and compile time safe syntax, using any language feature.
Have a look at the Express and Reflect classes in the Lokad Shared Libraries. Think they may help out with what you are trying to do. Read more here:
Strongly Typed Reflection in Lokad Shared
How to Find Out Variable or Parameter Name in C#?
From your comment: "I want an easy and compile time safe syntax to get information about members".
This is a very frequently requested feature and has been discussed in the C# team's meetings for about a decade, but has never been prioritised high enough to be included.
This blog post explains why:
http://blogs.msdn.com/ericlippert/archive/2009/05/21/in-foof-we-trust-a-dialogue.aspx
So for now, you're just going to be fighting against a missing feature. Maybe you could post more information about your broader problem and see if people can suggest different approaches.
Update
Without more info about your problem this is just guesswork. But if you have a property that represents a value but also carries additional "meta" information, you could always represent that as a new type and use an "injection" step to set everything up.
Here's a suggested abstract interface to such a "meta property":
public interface IMetaProperty<TValue>
{
TValue Value { get; set; }
string DisplayName { get; }
event Action<TValue, TValue> ValueChanged;
}
The value of the property is just another sub-property, with its type defined by the user.
I've put in the display name, and also as a bonus you've got an event that fires when the value changes (so you get "observability" for free).
To have properties like this in a class, you'd declare it like this:
public class SomeClass
{
public IMetaProperty<string> FirstName { get; private set; }
public IMetaProperty<string> LastName { get; private set; }
public IMetaProperty<int> Age { get; private set; }
public SomeClass() { MetaProperty.Inject(this); }
}
Note how the setters on the properties are private. This stops anyone from accidentally setting the property itself instead of setting the Value sub-property.
So this means the class has to set up those properties so they aren't just null. It does this by calling a magic Inject method, which can work on any class:
public static class MetaProperty
{
// Make it convenient for us to fill in the meta information
private interface IMetaPropertyInit
{
string DisplayName { get; set; }
}
// Implementation of a meta-property
private class MetaPropertyImpl<TValue> : IMetaProperty<TValue>,
IMetaPropertyInit
{
private TValue _value;
public TValue Value
{
get { return _value; }
set
{
var old = _value;
_value = value;
ValueChanged(old, _value);
}
}
public string DisplayName { get; set; }
public event Action<TValue, TValue> ValueChanged = delegate { };
}
public static void Inject(object target)
{
// for each meta property...
foreach (var property in target.GetType().GetProperties()
.Where(p => p.PropertyType.IsGenericType &&
p.PropertyType.GetGenericTypeDefinition()
== typeof(IMetaProperty<>)))
{
// construct an implementation with the correct type
var impl = (IMetaPropertyInit)
typeof (MetaPropertyImpl<>).MakeGenericType(
property.PropertyType.GetGenericArguments()
).GetConstructor(Type.EmptyTypes).Invoke(null);
// initialize any meta info (could examine attributes...)
impl.DisplayName = property.Name;
// set the value
property.SetValue(target, impl, null);
}
}
}
It just uses reflection to find all the IMetaProperty slots hiding in the object, and fills them in with an implementation.
So now a user of SomeClass could say:
var sc = new SomeClass
{
FirstName = { Value = "Homer" },
LastName = { Value = "Simpson" },
Age = { Value = 38 },
};
Console.WriteLine(sc.FirstName.DisplayName + " = " + sc.FirstName.Value);
sc.Age.ValueChanged += (from, to) =>
Console.WriteLine("Age changed from " + from + " to " + to);
sc.Age.Value = 39;
// sc.Age = null; compiler would stop this
If you're already using an IOC container you may be able to achieve some of this without going directly to reflection.
It looks like you're trying to create a static extension method?
DateTime yesterday = DateTime.Yesterday(); // Static extension.
Instead of
DateTime yesterday = DateTime.Now.Yesterday(); // Extension on DateTime instance.
If this is what you're trying to pull off, I do not believe it is possible in the current version of C#.
It sounds like you are integrating layers a little too tightly. Normally in this type of situation I would let the presentation layer decide the implementation of GetDisplayName() instead of making it an extension of the property itself. You could create an interface called MyTypeDisplayer or whatever you fancy, and let there be multiple implementations of it not limiting you to a single display implementation.
The issue here is that one cannot get a reference to non-static methods via instance MyType.[Member]. These can only be seen through a reference to an instance of the type. You also cannot build an extension method on-top of a type declaration, only on an instance of a type - that is the extension method itself has to be defined using an instance of a type (this T x).
One can however define the expression like this to get a reference to static members:
((MyType x) => MyType.Property)
One could do something similar to string displayName = ((MyType x) => x.Property).GetDisplayName();
The first issue is guaranteeing that the compiler treats your (x=> x.Property) as an Expression rather than an action/func etc...
To do this one might need to do this:
string displayName = ((Expression<Func<PropertyType>>)((MyType x) => x.Property).GetDisplayName();
The extension method would then have to be defined like this:
public static string GetDisplayName<T>(this Expression<Func<T>> expression)
You might also have to define an extension method on top of Expression<Action>> and Expression<Action<T>> if your members are also methods.
You can do a dot after an Expression - this is where the Compile method would reside.
Appended:
I think the static call to the extension method in cases that one doesn't have an instance of the type one needs to do "reflection" on to determine a Members name would be the cleanest syntax still - this way you could still use the extension method when using an instance of a type and fall back to the static call definition => MyExtensionClass.GetDisplayName(TypeOfX x => TypeOfX.StaticMember OR x.Property/Member) when one doesn't have an instance
If you interface your properties, you could make the extension on the interface instead:
namespace Linq1
{
class Program
{
static void Main(string[] args)
{
MyType o = new MyType();
o.Property.GetDisplayName();
}
}
public class MyType
{
public IDisplayableProperty Property { get; set; }
}
public interface IDisplayableProperty
{
string GetText();
}
public class MyProperty1 : IDisplayableProperty
{
public string GetText() { return "MyProperty2"; }
}
public class MyProperty2 : IDisplayableProperty
{
public string GetText() { return "MyProperty2"; }
}
public static class Extensions
{
public static string GetDisplayName(this IDisplayableProperty o)
{
return o.GetText();
}
}
}
The point of const-correctness is to be able to provide a view of an instance that can't be altered or deleted by the user. The compiler supports this by pointing out when you break constness from within a const function, or try to use a non-const function of a const object. So without copying the const approach, is there a methodology I can use in C# that has the same ends?
I'm aware of immutability, but that doesn't really carry over to container objects to name but one example.
I've come across this issue a lot of times too and ended up using interfaces.
I think it's important to drop the idea that C# is any form, or even an evolution of C++. They're two different languages that share almost the same syntax.
I usually express 'const correctness' in C# by defining a read-only view of a class:
public interface IReadOnlyCustomer
{
String Name { get; }
int Age { get; }
}
public class Customer : IReadOnlyCustomer
{
private string m_name;
private int m_age;
public string Name
{
get { return m_name; }
set { m_name = value; }
}
public int Age
{
get { return m_age; }
set { m_age = value; }
}
}
To get the benefit of const-craziness (or pureness in functional programming terms), you will need to design your classes in a way so they are immutable, just like the String class of c# is.
This approach is way better than just marking an object as readonly, since with immutable classes you can pass data around easily in multi-tasking environments.
I just wanted to note for you that many of the System.Collections.Generics containers have an AsReadOnly method which will give you back an immutable collection.
C# doesn't have such feature. You can pass argument by value or by reference. Reference itself is immutable unless you specify ref modifier. But referenced data isn't immutable. So you need to be careful if you want to avoid side effects.
MSDN:
Passing Parameters
Interfaces are the answer, and are actually more powerful than "const" in C++. const is a one-size-fits-all solution to the problem where "const" is defined as "doesn't set members or call something that sets members". That's a good shorthand for const-ness in many scenarios, but not all of them. For example, consider a function that calculates a value based on some members but also caches the results. In C++, that's considered non-const, although from the user's perspective it is essentially const.
Interfaces give you more flexibility in defining the specific subset of capabilities you want to provide from your class. Want const-ness? Just provide an interface with no mutating methods. Want to allow setting some things but not others? Provide an interface with just those methods.
Agree with some of the others look at using readonly fields that you initialize in the constructor, to create immutable objects.
public class Customer
{
private readonly string m_name;
private readonly int m_age;
public Customer(string name, int age)
{
m_name = name;
m_age = age;
}
public string Name
{
get { return m_name; }
}
public int Age
{
get { return m_age; }
}
}
Alternatively you could also add access scope on the properties, i.e. public get and protected set?
public class Customer
{
private string m_name;
private int m_age;
protected Customer()
{}
public Customer(string name, int age)
{
m_name = name;
m_age = age;
}
public string Name
{
get { return m_name; }
protected set { m_name = value; }
}
public int Age
{
get { return m_age; }
protected set { m_age = value; }
}
}
The const keyword can be used for compile time constants such as primitive types and strings
The readonly keyword can be used for run-time constants such as reference types
The problem with readonly is that it only allows the reference (pointer) to be constant. The thing referenced (pointed to) can still be modified. This is the tricky part but there is no way around it. To implement constant objects means making them not expose any mutable methods or properties but this is awkward.
See also Effective C#: 50 Specific Ways to Improve Your C# (Item 2 - Prefer readonly to const.)