I've started using MSpec recently, breaking classes into, Establish, Because and, It.
Although I know how to use them, I'm not sure what goes into making them work.
I know they are delegates
Because of = () =>
{
};
But when looking at how delegates are defined:
public delegate void Print(int value);
It looks like Establish, Because and, It are defined as delegates that return nothing (void) and take no arguments.
Which makes sense, but how are Establish, Because and, It distinguished from each other. I.e. What stops using It instead of Establish working just the same. And how does one of them know to use the other? i.e. It uses Establish
Also they just get put in the class. What Invokes them?
public class foobar: setup
{
private static int engineId;
Because of = () =>
{
};
It should = () =>
{
};
}
See the above has the delegates initialized to these functions. But I don't know how they get called and why this isn't okay:
public class foobar: setup
{
private static int engineId;
It of = () =>
{
};
It should = () =>
{
};
}
Can anyone clarify this for me please?
Those delegates are of different types, even though they all have the same signature. So they are distinguished based on their type. For example suppose you have this class from example usage:
[Subject("Authentication")]
public class When_authenticating_a_user
{
Establish context = () =>
{
Subject = new SecurityService();
};
Cleanup after = () =>
{
Subject.Dispose();
};
static SecurityService Subject;
}
And now you want to imitate running that test. You use reflection to get all fields first, because both context and after are fields:
var fields = typeof(When_authenticating_a_user).GetFields(BindingFlags.Instance | BindingFlags.NonPublic);
Now you have bunch of fields, but which is which? You can distinguish them by field type. One is of type Establish and another is of type Cleanup (both are delegate types with the same signature):
var establish = fields.FirstOrDefault(c => c.FieldType == typeof(Establish));
var cleanup = fields.FirstOrDefault(c => c.FieldType == typeof(Cleanup));
And then you create an instance and execute them according to some logic:
var instance = Activator.CreateInstance(typeof(When_authenticating_a_user));
// get method
var establishMethod = (Establish)establish.GetValue(instance);
// execute
establishMethod();
Yes, they're delegates, as declared here:
They're all parameterless void delegates, which are distinguished from each other in terms of how they're used in the framework. A method that accepts an It won't accept an Establish for example, so that indicated what the intention of the method is. Different delegates really are different types, even if they have the same signature. (You can create one delegate to wrap an instance of a different delegate type with a compatible signature, but that's relatively rare.)
I'm not saying I particularly like the framework or the names chosen, but having different delegates which happen to have the same signature makes perfect sense in terms of expressing the different intended meanings for those delegates.
Related
I am new to C# and still understanding the concept of delegates. What I know of delegates is that delegates define a function signature and functions with the same signature can be added to that delegate.
public class ss
{
public delegate void sampleDelegate();
public ss()
{
sampleDelegate s1 = new sampleDelegate(sampleMethod);
s1+= new sampleDelegate(sampleMethod2);
s1();
}
public static void sampleMethod()
{
}
public static void sampleMethod2()
{
}
}
In the above code I create a delegate and give it sampleMethod and sampleMethod2. When I call s1() it calls both sampleMethod() and sampleMethod2().
What if I want to only call one of those methods and that decision is to be made at runtime?
I may be missing something very small but delegates are really confusing to understand.
What if i want to only call one of those methods and that decision is to be made at runtime?
Then you don't combine them together, basically. For example:
// Names changed to be more conventional
SampleDelegate s1 = someCondition
? new SampleDelegate(SampleMethod)
: new SampleDelegate(SampleMethod2);
// This will call either SampleMethod or SampleMethod2, depending on condition
s1();
Note that normally I'd use a method group conversion, but you can't use method groups for the second and third operands of the conditional operator. You could use:
SampleDelegate s1;
if (condition) {
s1 = SampleMethod;
} else {
s2 = SampleMethod2;
}
... or
SampleDelegate s1 = someCondition
? new SampleDelegate(SampleMethod)
: SampleMethod2;
Neither of these looks particularly nice to me though.
Delegates are like pointers to a method. At run-time, there's nothing that differentiates calling a delegate or a method excluding that a method is a member of an object:
some.Method();
someDelegate();
The goal of delegates is creating a blackbox where you expect some code to put some behavior, and you simply rely on a method signature.
At the end of the day, they're like method interfaces:
// It must be a parameterless method which returns no value
public delegate void Action();
// vs
// It must be a class which implements a parameterless method "Do"
// which returns no value
public interface Action
{
void Do();
}
That is, a method can't be conditionally be switched with other, but you need to use regular control flow blocks like if or switch to take decisions about what to do.
In order to don't duplicate Jon Skeet's answer, I'll add another possible solution:
string text = "";
sampleDelegate s1 = () =>
{
if(!string.IsNullOrEmpty(text))
{
SampleMethod1();
}
else
{
SampleMethod2();
}
};
s1();
Check that, instead of creating two instances of sampleDelegate you can create one that handles the conditional logic to either call SampleMethod1 or SampleMethod2.
The whole () => { } thing is called anonymous delegate.
It can be also expressed as follows:
string text = "";
sampleDelegate s1 = delegate()
{
if(!string.IsNullOrEmpty(text))
{
SampleMethod1();
}
else
{
SampleMethod2();
}
};
But don't use above syntax... It comes from the old .NET days (.NET 1.0/1.1/2.0).
In summary, a delegate could or could not be provided as an actual class method, but you can combine class methods with anonymous delegates to meet your needs.
What if i want to only call one of those methods and that decision is
to be made at runtime? I may be missing something very small but
delegates are really confusing to understand.
Actually this is the reason to use delegates, but you're right when you say you're missing something.
Delegates are used to situations like the following one:
public void DoStuff(string text, Func<string, string> textFormatter = null)
{
Console.WriteLine(textFormatter != null ? textFormatter(text) : text);
}
You might call DoStuff either this way DoStuff("hello world") or DoStuff("hello world", text => $"<strong>{text}</strong>").
DoStuff method implementation doesn't know how to format the given text, and you provide an optional parameter to give a delegate as argument that will receive the whole text to format and it will return the formatted text.
Isn't this some way conditional after all? Based on the caller, DoStuff formats the text in a custom way. You can even provide a default format:
public void DoStuff(string text, Func<string, string> textFormatter = null)
{
// We'll give a default formatter if none is provided ;)
if(textFormatter == null)
textFormatter = text => $"<span>{text}</span>";
Console.WriteLine(textFormatter(text));
}
I have create an object using this syntax:
var newMessage = Activator.CreateInstance(client.Key);
It appears to create an object of the correct type and allows the object properties to be set. However when I pass the object to a method with signature:
public void Publish<T>(T messageBody)
The Type defined by T is object.
How do I get around this? I can't change the method signature - its from a library - and I need to be able to create objects at runtime without knowing their type beforehand.
UPDATED
The function I am trying to perform relates to sending(Publishing) messages. Ordinarily I would register a message Handler like:
RegisterHandler<MyMessage> (m => do something with message );
and could then call
Publish<MyMessage> (message)
which would eventually end up at the handler. This is cool and works fine.
What I am trying to do is insert an intermediary to act as an exchange and publish the message to multiple handlers. I know there are other things I could use to do this for me such as RabbitMQ, but I was hoping to be able to achieve it with just a small modification to the current code.
So I have a method that registers subscriptions:
public virtual void registerSubscription<T1,T2>()
{
if (handlerMap.ContainsKey(typeof(T2)))
{
throw new ArgumentException("Message handler has already been registered for type: " +typeof(T2).Name);
}
if (!handlerMap.ContainsValue(typeof(T1)))
{
mqHost.RegisterHandler<T1> (m => distributeMessage(m) );
}
handlerMap[typeof(T2)] = typeof(T1);
}
I call the method with two classes, a base class and a class that inherits the base class:
public class MyMessage
{
public string name {get;set;}
}
public class MyMessage2:MyMessage{}
This bit works well and I get a map of handlers built up. The problem comes when I do the next bit, the distributeMessage method.
var match = handlerMap.Where(i => i.Value == message.Body.GetType());
foreach (var client in match)
{
var newMessage = Activator.CreateInstance(client.Key);
newMessage.PopulateWith(message.Body);
messageProducer.Publish(createMessage(newMessage));
}
The messageProducer.publish has the signature:
public void Publish<T>(T messageBody)
I can't (easily) modify this - it is part of a library. There is another method I could call:
public void Publish<T>(IMessage<T> message)
But I can't see that this would be any easier as I would have to create a Message which still requires .
You can use some reflection to try to create a generic method of Publish given the type information you knew when calling the Activator. If I have misunderstood what you are trying to do, please ask and I can modify this code.
object newObject = Activator.CreateInstance(myType);
var publishMethod = typeof(MessageProducer).GetMethod("Publish");
var publishMethodWithCorrectType = publishMethod.MakeGenericMethod(new Type[] { myType });
publishMethodWithCorrectType.Invoke(messageProducer, new object[]{newObject});
I hope this helps.
Try do this:
var newMessage = (MyType)Activator.CreateInstance(client.Key);
p.s. MyType is an base type or interface...
You would need to invoke the Publish<T> method via reflection as well to continue along this route.
Another suggestion would be to make the class object's class generic based on the client.Key type, then implement a Publish method within that class - the implementation will know what T is.
Found this answer to another question
and implemented this:
typeof(MessageExchange)
.GetMethod("createMessage",BindingFlags.Static | BindingFlags.NonPublic)
.MakeGenericMethod(newMessage.GetType())
.Invoke(null, new object[] { newMessage });
I'm now getting the correct type being passed through.
When working with existing frameworks, sometimes you need to pass in an action delegate which performs no action usually an extension point added by the original developer. Example:
var anObject = new Foo(() => { });
And presumably the Foo object will call this delegate at some time. My goal here is to eliminate the use of { }, because my style dictates that { } need to be on their own, and separate lines, and I'm a bit OCD and hate being verbose if I don't have to be.
When dealing with an action which returns a value, this is simple enough- you can provide an expression instead of a statement (thus eliminating the braces.) Example:
var anObject = new Foo(() => string.Empty);
So, I suppose the question is two parts...
Does .NET have any sort of default empty action?
Is there syntactic sugar for providing an empty expression to a lambda, other than { }?
The current solution I'm leaning towards is to define the delegate in a preceding assignment to avoid having to use the lambda expressing inside a function invocation.
There's nothing built-in that I'm aware of.
You could just define the delegate once as a helper singleton:
var anObject = new Foo(NoOpAction.Instance);
// ...
var anotherObject = new Bar(NoOpAction.Instance);
// ...
public static class NoOpAction
{
private static readonly Action _instance = () => {};
public static Action Instance
{
get { return _instance; }
}
}
And because you're handed exactly the same delegate every time you use NoOpAction.Instance throughout your program, you're also saving on the (admittedly small) cost of creating and garbage-collecting multiple delegates that all do the same thing.
I am trying run a 'Recipe' read from a text file and parsed line by line to dynamically call a series of methods. I think I need to implement a Factory after doing quite a bit of googling, but I am lacking some key details. This is the closest example I have:
http://simpleprogrammer.com/2010/08/17/pulling-out-the-switch-its-time-for-a-whooping/
The following code is a snippet of what have now.
internal static void Run(int Thread_ID, List<StringBuilder> InstructionSet, List<double>[] Waveforms)
{
//Init
List<double>[] Register = new List<double>[10];
for (int i = 0; i < Waveforms.Length; i++) { Register[i] = new List<double>(Waveforms[i]); }
for (int i = 0; i < Register.Length; i++) { if (Register[i] == null) { Register[i] = new List<double>(); } }
//Run Recipe Steps
foreach (var item in InstructionSet)
{
Step Op = Step.Parse(item.ToString());
switch (Op.TaskName)
{
case "SimpleMovingAverage":
Register[Convert.ToInt32(Op.Args[0])] = Signal_Filters.SimpleMovingAverage(Register[Convert.ToInt32(Op.Args[1])], Convert.ToInt32(Op.Args[2]));
break;
case "RollingSteppedStdDeviation":
Register[Convert.ToInt32(Op.Args[0])] = Signal_Filters.RollingSteppedStdDeviation(Register[Convert.ToInt32(Op.Args[1])], Convert.ToInt32(Op.Args[2]), Convert.ToInt32(Op.Args[3]));
break;
//... etc. many, many methods to be called.
}
}
}
... and below is the portion of the example I have questions about:
public static class MoveFactory
{
private static Dictionary<string, Func<IMove>> moveMap = new Dictionary<string, Func<IMove>>()
{
{"Up", () => { return new UpMove(); }},
{"Down", () => { return new DownMove(); }},
{"Left", () => { return new LeftMove(); }}
// ...
};
public static IMove CreateMoveFromName(string name)
{
return moveMap[name]();
}
}
Can I generate the Dictionary list automatically? So that whenever I add a new class that implements my Factory Interface (my equivalent of IMove), I don't have to update my dictionary or pretty much any other part of my code. Perhaps this can forced as part of the Interface?
In the above example code, I don't see it passing arguments in and out. Looking at my code I have data I need to mutate progressively... How would I do this using a Factory.
The Factory needs to be thread-safe as I want to pass different initial data to multiple workers each running their own recipe.
Let's tackle these one at a time.
Building The Dictionary Dynamically
This is actually pretty easy to do using a combination of Reflection and Custom Attributes.
The creation of an Attribute is pretty trivial, so I'll leave that to you to look up, but let's assume you have one called MoveNameAttribute that can be applied at a class level. You can then decorate your classes that implement IMove like so:
[MoveName("Up")]
class UpMove: IMove{}
[MoveName("Down")]
class DownMove: IMove{}
Now you can use Reflection and a little LINQ to extract these class types into a dictionary, and create new instances of those types on demand using the key specified in your custom attribute.
While the entire Factory itself is pretty short in terms of lines of code, Reflection can be daunting if you have never done it before. I've annotated every line to explain what is going on.
internal static class MoveFactory
{
private static readonly IDictionary<String, Type> _moveTypes;
static MoveFactory()
{
_moveTypes = LoadAllMoveTypes();
}
private static IDictionary<string, Type> LoadAllMoveTypes()
{
var asm =
//Get all types in the current assembly
from type in Assembly.GetExecutingAssembly().GetTypes()
//Where the type is a class and implements "IMove"
where type.IsClass && type.GetInterface("IMove") != null
//Only select types that are decorated with our custom attribute
let attr = type.GetCustomAttribute<MoveNameAttribute>()
where attr != null
//Return both the Name and the System.Type
select new
{
name = attr.Name,
type
};
//Convert the results to a Dictionary with the Name as a key
// and the Type as the value
return asm.ToDictionary(move => move.name, move => move.type);
}
internal static IMove CreateMove(String name)
{
Type moveType;
//Check to see if we have an IMove with the specific key
if(_moveTypes.TryGetValue(name, out moveType))
{
//Use reflection to create a new instance of that IMove
return (IMove) Activator.CreateInstance(moveType);
}
throw new ArgumentException(
String.Format("Unable to locate move named: {0}", name));
}
}
Now that you have your factory, you can simply create new instances like this:
var upMove = MoveFactory.CreateMove("Up");
var downMove = MoveFactory.CreateMove("Down");
Since the factory uses a Static Constructor, it will only populate this list once, and will automatically pick up your new classes.
Passing Arguments
I'm not 100% sure what your use case is here, but it doesn't look like you need to pass arguments to your Factory, rather to some method on your IMove. However, you have a variable number of arguments that can be passed in.
If this is the case, then you are simply going to have to live with a bit of ugliness in your design. You need a very generic method on your IMove interface:
public interface IMove
{
double Compute(double val1, params int[] args);
}
Now your individual move classes are going to have to just be diligent and check to ensure that they get the proper number of parameters. I'll leave this as an exercise for you, but this should give you what you need based on the example above.
Thread Safety
As it stands the factory implementation above is thread safe because it doesn't rely on any shared state, and the underlying dictionary is essentially immutable. Each call to CreateMove returns a brand new IMove instance.
Now whether or not your implementations of IMove are thread safe is up to you :)
Whew! That was a long answer, but hopefully this will help you out.
I'm creating a framework that contains a wrapper around a library (specifically SharpBrake) that performs all interaction with SharpBrake via reflection so there's no hard dependency on the library to 3rd parties of my framework.
If 3rd parties of my framework wants to use SharpBrake, they can just stuff the SharpBrake.dll into the bin folder, but if they don't, they can just forget about it. If my framework had explicit references to SharpBrake types, users of my framework would get exceptions during runtime of SharpBrake.dll missing, which I don't want.
So, my wrapper first loads SharpBrake.dll from disk, finds the AirbrakeClient type, and stores a delegate pointing to the AirbrakeClient.Send(AirbrakeNotice) method in a private field. My problem, however, is that since the Send() method takes an AirbrakeNotice object and I can't reference the AirbrakeNotice object directly, I need to somehow convert the Send() method to an Action<object>.
I have a strong feeling this isn't possible, but I want to explore all options before settling on exposing Delegate and using DynamicInvoke(), which I assume is far from optimal, performance-wise. What I would love to do is the following:
Type clientType = exportedTypes.FirstOrDefault(type => type.Name == "AirbrakeClient");
Type noticeType = exportedTypes.FirstOrDefault(type => type.Name == "AirbrakeNotice");
MethodInfo sendMethod = clientType.GetMethod("Send", new[] { noticeType });
object client = Activator.CreateInstance(clientType);
Type actionType = Expression.GetActionType(noticeType);
Delegate sendMethodDelegate = Delegate.CreateDelegate(actionType, client, sendMethod);
// This fails with an InvalidCastException:
Action<object> sendAction = (Action<object>)sendMethodDelegate;
However, this fails with the following exception:
System.InvalidCastException: Unable to cast object of type 'System.Action`1[SharpBrake.Serialization.AirbrakeNotice]' to type 'System.Action`1[System.Object]'.
Obviously, because sendMethodDelegate is an Action<AirbrakeNotice> and not an Action<object>. Since I can't mention AirbrakeNotice in my code, I'm forced to do this:
Action<object> sendAction = x => sendMethodDelegate.DynamicInvoke(x);
or just exposing the Delegate sendMethodDelegate directly. Is this possible? I know that there's chance of getting into situations where the object can be of a different type than AirbrakeNotice which would be bad, but seeing how much you can mess up with reflection anyway, I'm hoping there's a loophole somewhere.
If you're happy to use expression trees, it's reasonably simple:
ConstantExpression target = Expression.Constant(client, clientType);
ParameterExpression parameter = Expression.Parameter(typeof(object), "x");
Expression converted = Expression.Convert(parameter, noticeType);
Expression call = Expression.Call(target, sendMethod, converted);
Action<object> action = Expression.Lambda<Action<object>>(call, parameter)
.Compile();
I think that's what you want...
If you don't need below C# 4 support you can get much greater performance using the dynamic vs DynamicInvoke.
Action<dynamic> sendAction = x => sendMethodDelegate(x);
Actually I guess you wouldn't even need the above if you can use dynamic, because it would increase performance and simplify everything if you just did:
Type clientType = exportedTypes.FirstOrDefault(type => type.Name == "AirbrakeClient");
dynamic client = Activator.CreateInstance(clientType);
...
client.Send(anAirbrakeNotice);
But if you need to support .net 3.5 jon skeets answer with expression trees is definitely the way to go.
From my comment on the OP:
I'd avoid extended use of reflections if you are concerned about performance. If you can come up with an interface for the class(es) you are using, then I'd create one. Then write a wrapper that implements the interface by calling into the SharpBreak code, and stuff it in a separate DLL. Then dynamically load just your wrapper assembly and concrete wrapper type(s), and call into that interface. Then you don't have to do reflections at a method level.
I'm not sure all the classes you'd need, but here's a simple example of how you can hook into that library with loose coupling based on interfaces.
In your program's assembly:
public IExtensions
{
void SendToAirbrake(Exception exception);
}
public static AirbreakExtensions
{
private static IExtensions _impl;
static()
{
impl = new NullExtensions();
// Todo: Load if available here
}
public static void SendToAirbrake(this Exception exception)
{
_impl.SendToAirbrake(exception);
}
}
internal class NullExtensions : IExtensions // no-op fake
{
void SendToAirbrake(Exception exception)
{
}
}
In a load-if-available (via reflections) assembly
public ExtensionsAdapter : IExtensions
{
void SendToAirbrake(Exception exception)
{
SharpBrake.Extensions.SendToAirbrake(exception);
}
}
The advantage of this approach is that you only use reflections once (on load), and never touch it again. It is also simple to modify to use dependency injection, or mock objects (for testing).
Edit:
For other types it will take a bit more work.
You might need to use the Abstract Factory pattern to instantiate an AirbrakeNoticeBuilder, since you need to deal directly with the interface, and can't put constructors in interfaces.
public interface IAirbrakeNoticeBuilderFactory
{
IAirbrakeNoticeBuilder Create();
IAirbrakeNoticeBuilder Create(AirbrakeConfiguration configuration);
}
If you're dealing with custom Airbreak structures, you'll have even more work.
E.g. for the AirbrakeNoticeBuilder you will have to create duplicate POCO types for any related classes that you use.
public interface IAirbrakeNoticeBuilder
{
AirbrakeNotice Notice(Exception exception);
}
Since you're returning AirbrakeNotice, you might have to pull in nearly every POCO under the Serialization folder, depending on how much you use, and how much you pass back to the framework.
If you decide to copy the POCO code, including the whole object tree, you could look into using AutoMapper to convert to and from your POCO copies.
Alternately, if you don't use the values in the classes you're getting back, and just pass them back to the SharpBreak code, you could come up with some sort of opaque reference scheme that will use a dictionary of your opaque reference type to the actual POCO type. Then you don't have to copy the whole POCO object tree into your code, and you don't need to take as much runtime overhead to map the object trees back and forth:
public class AirbrakeNotice
{
// Note there is no implementation
}
internal class AirbreakNoticeMap
{
static AirbreakNoticeMap()
{
Map = new Dictionary<AirbreakNotice, SharpBreak.AirbreakNotice>();
}
public static Dictionary<AirbreakNotice, SharpBreak.AirbreakNotice> Map { get; }
}
public interface IAirbrakeClient
{
void Send(AirbrakeNotice notice);
// ...
}
internal class AirbrakeClientWrapper : IAirbrakeClient
{
private AirbrakeClient _airbrakeClient;
public void Send(AirbrakeNotice notice)
{
SharpBreak.AirbrakeNotice actualNotice = AirbreakNoticeMap.Map[notice];
_airbrakeClient.Send(actualNotice);
}
// ...
}
internal class AirbrakeNoticeBuilderWrapper : IAirbrakeNoticeBuilder
{
AirbrakeNoticeBuilder _airbrakeNoticeBuilder;
public AirbrakeNotice Notice(Exception exception)
{
SharpBreak.AirbrakeNotice actualNotice =
_airbrakeNoticeBuilder.Notice(exception);
AirbrakeNotice result = new AirbrakeNotice();
AirbreakNoticeMap.Map[result] = actualNotice;
return result;
}
// ...
}
Keep in mind that you only need to wrap the classes and parts of the public interface that you're going to use. The object will still behave the same internally, even if you don't wrap its entire public interface. This might mean you have to do less work, so think hard and try to wrap only what you need now, and what you know you're going to need in the future. Keep YAGNI in mind.
The programming style I have come to really like for problems like this is to write as much strongly-typed code as possible, and then hand off the logic from the dynamically-typed code to the strongly-typed code. So I would write your code like this:
//your code which gets types
Type clientType = exportedTypes.FirstOrDefault(type => type.Name == "AirbrakeClient");
Type noticeType = exportedTypes.FirstOrDefault(type => type.Name == "AirbrakeNotice");
//construct my helper object
var makeDelegateHelperType=typeof(MakeDelegateHelper<,>).MakeGenericType(clientType, noticeType);
var makeDelegateHelper=(MakeDelegateHelper)Activator.CreateInstance(makeDelegateHelperType);
//now I am in strongly-typed world again
var sendAction=makeDelegateHelper.MakeSendAction();
And this is the definition of the helper object, which is able to get away with fewer reflectiony calls.
public abstract class MakeDelegateHelper {
public abstract Action<object> MakeSendAction();
}
public class MakeDelegateHelper<TClient,TNotice> : MakeDelegateHelper where TClient : new() {
public override Action<object> MakeSendAction() {
var sendMethod = typeof(TClient).GetMethod("Send", new[] { typeof(TNotice) });
var client=new TClient();
var action=(Action<TNotice>)Delegate.CreateDelegate(typeof(Action<TNotice>), client, sendMethod);
return o => action((TNotice)o);
}
}