How to access and set static property value in TestMethod - c#

How to access and set StaticProperty
public static class StaticClass
{
private bool? _staticValue = null;
public bool StaticProperty => _staticValue ?? ((bool)(_staticValue = GetStaticPropertyValue()));
public static bool GetStaticPropertyValue()
{
//get value
}
}
inside Test Method,
[TestMethod]
public void UnitTestSomeMethod()
{
var consumeClass = new ConsumeClass();
consumeClass.SomeMethod();
}
so that isEnabled variable is set to true in ConsumeClass.SomeMethod
public class ConsumeClass
{
public void SomeMethod()
{
var isEnabled = StaticClass.StaticProperty;
if(isEnabled)
{
//do something
}
}
}

The way your code currently looks like there´s only a dirty way using reflection, because there´s no setter for your property:
var property = typeof(StaticClass).GetProperty("StaticProperty", BindingFlags.Static)?.GetBackingField().SetValue(null, true);
This sometimes is neccessary for large legacy-systems that you can´t easily change but you have the need for unit-tests. However you should change the system as soon as possible, e.g. by using an internal setter:
public static bool StaticProperty { get; internal set; }
and add the InternalsVisibleTo-attribute to your assemby, in order to access its internal members within your test-assembly.
As per your edit the reflection-based approach is a bit easier, as you have a named backing-field which you can assign a new value:
typeof(StaticClass).GetField("_staticValue", BindingFlags.Static).SetValue(null, true);
However be aware that variable-names may change, so the above may fail at runtime when someone renames the backing-field.

Related

Does a simple property need synchronization? [duplicate]

I would like to know if C# automatically implemented properties, like public static T Prop { get; set; }, are thread-safe or not. Thanks!
Section 10.7.4 of the C# specification states:
When a property is specified as an
automatically implemented property, a
hidden backing field is automatically
available for the property, and the
accessors are implemented to read from
and write to that backing field. The
following example:
public class Point {
public int X { get; set; } // automatically implemented
public int Y { get; set; } // automatically implemented
}
is equivalent to the following declaration:
public class Point {
private int x;
private int y;
public int X { get { return x; } set { x = value; } }
public int Y { get { return y; } set { y = value; } }
}
That's what we promise, and that's what you get. The point of auto properties is to do the most basic, simple, cheap thing; if you want to do something fancier then you should write a "real" property.
It appears not. This is the decompilation with Reflector:
private static string Test
{
[CompilerGenerated]
get
{
return <Test>k__BackingField;
}
[CompilerGenerated]
set
{
<Test>k__BackingField = value;
}
}
No. You must wrap them in thread-locking mechanisms.
object _lock = new object();
public static Main(string[] args)
{
lock(_lock)
{
Prop = new T();
}
T val = null;
lock(_lock)
{
val = Prop;
}
}
There is no synchronization provided with automatic properties, including static properties.
If you need full thread safety, you'll want to use your own properties with a backing field, and handle the synchronization yourself.
For completeness, field-like events do have thread-safety built in, but they are alone in this. Automatically implemented properties do not have any such features. You can, however, do something like:
public static double SomeProp
{ // ### NOT RECOMMENDED ###
[MethodImpl(MethodImplOptions.Synchronized)] get;
[MethodImpl(MethodImplOptions.Synchronized)] set;
}
The problem with this is that it will lock the Type, which is a bad thing. I would implement my own synchronization for this, personally.
I don't believe so. I believe they are just syntatic sugar for:
private static T _prop;
public static T Prop
{
get { return _prop; }
set { _prop = value; }
}
No, they not threadsafe. Static properties just as vulnerable as static fields are to concurrency issues.

How do I set a property in my dynamic code

I want to be able to store code in a database and then execute it dynamically (using Roslyn). However, I want to be able to (inject?) properties from calling code. See below:
using Roslyn.Scripting.CSharp;
using RoslynMVCTest.Interfaces;
namespace RoslynMVCTest.Services
{
public class MyService
{
private readonly IInjectedService _injectedService;
public MyService(IInjectedService injectedService)
{
_injectedService = injectedService;
}
public bool SomeMethod()
{
string codeString = #"
using RoslynMVCTest.Interfaces;
public class SomethingDoer
{
public IInjectedService InjectedService {get;set;}
public static bool DoSomething()
{
return IInjectedService.SomeOtherMethod();
}
}";
var engine = new ScriptEngine();
var session = engine.CreateSession(_injectedService);
session.AddReference(this.GetType().Assembly);
//How do I set the property in my dynamic code to _injectedService??
var result = session.Execute<bool>("SomethingDoer.DoSomething()");
return result;
}
}
}
I realize there are probably syntax and other issues here, but it's a good representation of what I want to do. Is there a way to do this?
First I'm going to answer your question matching your original code as closely as possible. Second, I'm going to show a far more concise example that might in fact be all that you're after.
You can certainly declare your type as you've done, but a few things will have to be fixed to even get it to make sense.
Your SomethingDoer class declares a non-static InjectedService property, despite the fact that you attempt to consume that property in a static method. I will assume for the sake of discussion that you intended SomethingDoer.DoSomething to be non-static as well and will thus instanatiate that class.
public static bool DoSomething()
To:
public bool DoSomething()
The "sesion" you pass to CreateSession is your actual service. To understand why this won't work, you have to understand what the argument you pass to CreateSession means and what's done with it. What the "session" means is that all the public properties of that object are available to your scripting session as raw identifiers without the need to . reference them on any target. Thus, to get your code working, I've introduced a new class (inner to the main service class for convenience) called Session:
public class Session
{
public IInjectedService InjectedService { get; set; }
}
Furthermore, I've used this new class when invoking CreateSession:
var session = engine.CreateSession(new Session { InjectedService = _injectedService });
What this means is that the property InjectedService is now available to you within your codeString.
Perhaps most importantly, your code codeString is never actually consumed by your code! You seem to have, understandably, conceived of this process as setting up a string for your code, and then imagined that you could then invoke some arbitrary method within it. On the contrary, there is only one block of code. So if you really want to declare a whole class in your script-code, you're still going to have to consume it directly within your script-code as well. This means that the final two lines of your codeString should actually look like:
var somethingDoer = new SomethingDoer { InjectedService = InjectedService };
somethingDoer.DoSomething()";
Here we're instantiating SomethingDoer (because of change 1.) and setting the service property by the implicit InjectedService value provided by the session (because of change 2.).
For completeness, here is the fully working sample code:
namespace RoslynMVCTest.Interfaces
{
public interface IInjectedService
{
bool SomeOtherMethod();
}
}
namespace RoslynMVCTest.Services
{
using RoslynMVCTest.Interfaces;
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new MyService(new InjectedService()).SomeMethod());
Console.ReadLine();
}
}
class InjectedService : IInjectedService
{
public bool SomeOtherMethod()
{
return true;
}
}
public class MyService
{
private readonly IInjectedService _injectedService;
public MyService(IInjectedService injectedService)
{
_injectedService = injectedService;
}
public class Session
{
public IInjectedService InjectedService { get; set; }
}
public bool SomeMethod()
{
string codeString = #"
using RoslynMVCTest.Interfaces;
public class SomethingDoer
{
public IInjectedService InjectedService { get; set; }
public bool DoSomething()
{
return InjectedService.SomeOtherMethod();
}
}
var somethingDoer = new SomethingDoer { InjectedService = InjectedService };
somethingDoer.DoSomething()";
var engine = new ScriptEngine();
var session = engine.CreateSession(new Session { InjectedService = _injectedService });
session.AddReference(this.GetType().Assembly);
//How do I set the property in my dynamic code to _injectedService??
var result = session.Execute<bool>(codeString);
return result;
}
}
}
Alternative Approach
If all you want to do is allow your script to run some code that interacts with your service, you can see how this is actually extremely trivial given all the points made above. Thus to concisely express what might be the intent of your original code, all you'd have to do is:
var result = session.Execute<bool>("InjectedService.SomeOtherMethod()");
The code passed in here is simply the body of the service method in the long-winded first example. Quite possibly this is all you need or want.

What's the difference between a property with a private setter and a property with no setter?

If I want a read-only property, I write it like:
public int MyProperty { get { //Code goes here } }
However, the Microsoft example (and a few other examples I've seen) are written like:
public int MyProperty { get; private set; }
Is there any difference between these two, and should I start writing properties like this?
As you can see in your second sample, you can leave out the implementation for a property. .NET will then automatically create a local variable for the property and implement simple getting and setting.
public int MyProperty { get; private set; }
is actually equivalent to
private int _myProperty;
public int MyProperty {
get { return _myProperty; }
private set { _myProperty = value; }
}
Writing
public int MyProperty { get; }
does not work at all, as automatic properties need to implement a getter and a setter, while
public int MyProperty { get; private set; }
leaves you with a property that may return any int, but can only be changed within the current class.
public int MyProperty { get { ... } }
creates a read-only property.
Question is: what do you need? If you already have a member variable that's used within your class and you only want to return the current value using a property, you're perfectly fine with
public int MyProperty { get { return ...; }}
However, if you want a read-only property, which you need to set within your code (but not from other classes) without explicitly declaring a member variable, you have to go with the private set approach.
With private setter you can only assign property value inside of instance when property is without setter you can't set its value anywhere.
If you don't use an explicit member assignment in the property, you'll have to declare a private set at least in order to be able to set a value to this property. Otherwise, you'll get a warning at compile-time saying that your property cannot be assigned.
If you use an explicit member, you'll be able to assign a value to this member directly, without needing to add a private set:
private int member ;
public int MyProperty {
get { return member; }
}
// ...
member = 2;
int anotherVariable = MyProperty; // anotherVariable == 2
public int MyProperty
{
get
{
// Your own logic, like lazy loading
return _myProperty ?? (_myProperty = GetMyProperty());
}
}
A property with only a getter is very useful if you need your own logic behind the access of that property, in particular when you need the property to be lazy loaded.
public int MyProperty { get; private set; }
A property with a private setter is useful if you need the property not te be changed from the outside, but still maintained from within the class.
In both cases, you can have a backing data field for the actual value, but in the former, you'll have to maintain that yourself, and in the latter, it is maintained for you by the generated code.
There is a difference when you access the object with reflection.
public class Foo
{
public string Bar { get; private set; }
}
// .....
internal static void Main()
{
Foo foo = new Foo();
foo.GetType().GetProperty("Bar").SetValue(foo, "private?", null);
Console.WriteLine(foo.Bar);
}

Are C# auto-implemented static properties thread-safe?

I would like to know if C# automatically implemented properties, like public static T Prop { get; set; }, are thread-safe or not. Thanks!
Section 10.7.4 of the C# specification states:
When a property is specified as an
automatically implemented property, a
hidden backing field is automatically
available for the property, and the
accessors are implemented to read from
and write to that backing field. The
following example:
public class Point {
public int X { get; set; } // automatically implemented
public int Y { get; set; } // automatically implemented
}
is equivalent to the following declaration:
public class Point {
private int x;
private int y;
public int X { get { return x; } set { x = value; } }
public int Y { get { return y; } set { y = value; } }
}
That's what we promise, and that's what you get. The point of auto properties is to do the most basic, simple, cheap thing; if you want to do something fancier then you should write a "real" property.
It appears not. This is the decompilation with Reflector:
private static string Test
{
[CompilerGenerated]
get
{
return <Test>k__BackingField;
}
[CompilerGenerated]
set
{
<Test>k__BackingField = value;
}
}
No. You must wrap them in thread-locking mechanisms.
object _lock = new object();
public static Main(string[] args)
{
lock(_lock)
{
Prop = new T();
}
T val = null;
lock(_lock)
{
val = Prop;
}
}
There is no synchronization provided with automatic properties, including static properties.
If you need full thread safety, you'll want to use your own properties with a backing field, and handle the synchronization yourself.
For completeness, field-like events do have thread-safety built in, but they are alone in this. Automatically implemented properties do not have any such features. You can, however, do something like:
public static double SomeProp
{ // ### NOT RECOMMENDED ###
[MethodImpl(MethodImplOptions.Synchronized)] get;
[MethodImpl(MethodImplOptions.Synchronized)] set;
}
The problem with this is that it will lock the Type, which is a bad thing. I would implement my own synchronization for this, personally.
I don't believe so. I believe they are just syntatic sugar for:
private static T _prop;
public static T Prop
{
get { return _prop; }
set { _prop = value; }
}
No, they not threadsafe. Static properties just as vulnerable as static fields are to concurrency issues.

Is it possible to have fields that are assignable only once?

I need a field that can be assigned to from where ever I want, but it should be possible to assign it only once (so subsequent assignments should be ignored). How can I do this?
That would not be a readonly field then. Your only options for initializing real readonly fields are field initializer and constructor.
You could however implement a kind of readonly functionality using properties. Make your field as properties. Implement a "freeze instance" method that flipped a flag stating that no more updates to the readonly parts are allowed. Have your setters check this flag.
Keep in mind that you're giving up a compile time check for a runtime check. The compiler will tell you if you try to assign a value to a readonly field from anywhere but the declaration/constructor. With the code below you'll get an exception (or you could ignore the update - neither of which are optimal IMO).
EDIT: to avoid repeating the check you can encapsulate the readonly feature in a class.
Revised implementation could look something like this:
class ReadOnlyField<T> {
public T Value {
get { return _Value; }
set {
if (Frozen) throw new InvalidOperationException();
_Value = value;
}
}
private T _Value;
private bool Frozen;
public void Freeze() {
Frozen = true;
}
}
class Foo {
public readonly ReadOnlyField<int> FakeReadOnly = new ReadOnlyField<int>();
// forward to allow freeze of multiple fields
public void Freeze() {
FakeReadOnly.Freeze();
}
}
Then your code can do something like
var f = new Foo();
f.FakeReadOnly.Value = 42;
f.Freeze();
f.FakeReadOnly.Value = 1337;
The last statement will throw an exception.
Try the following:
class MyClass{
private int num1;
public int Num1
{
get { return num1; }
}
public MyClass()
{
num1=10;
}
}
Or maybe you mean a field that everyone can read but only the class itself can write to? In that case, use a private field with a public getter and a private setter.
private TYPE field;
public TYPE Field
{
get { return field; }
private set { field = value; }
}
or use an automatic property:
public TYPE Field { get; private set; }

Categories

Resources