Using Func<T,TResult> c# - c#

I am working on PCL which along with a lot of functionality also provides log in. Also I recently started using delegates.
The Current Case:
I have a Simple methods that takes in parameters and provide GPlus, Facebook or Simple logIn with Username and Password. as in the code below:
public async Task<SignInResponse> SignInUsingFacebook(IFacebookInitializer faceBookConfiguration)
{
//my code
}
public async Task<SignInResponse> SignInUserNameAndPass(string username,string password)
{
//my code
}
public async Task<SignInResponse> SignInUsingGPlus(IGPlusInitializer gPlusConfiguration)
{
//my code
}
This is great, I can call them from my application directly and handle data but,
I recently came across Delegates and Func<T,TResult>
What I want to do:
I want a simple method that takes in a parameter an enum of LogInType as below:
public enum LogInType
{
UserNameAndPassword,
Facebook,
GooglePlus,
}
and based on the type of login type provided to the method, handles the LogIn process on it's own and just returns the SignInResponse object.
Is there a way this can be done using Delegates. Rather than having 3 individual methods to call for each case. If yes, then can someone please help in the parameters to be passed to the Single method along with The LogInType. I know it has to be a Func but what would the Func look like as it has to take 3 different parameters.
As From the Comments:
Each of those methods is a different signature anyway so you have a Func<IFacebookInitializer, Task<SignInResponse>>, Func<string, string, Task<SignInResponse>> and Func<IGPlusInitializer, Task<SignInResponse>> so you'd still end up with an if statement.
Can I return a Func when the method is called? this ways I can return either of the three func based on a quick switch case. The issue would be (if it's possible) what would be the generic response (or the common response) type of the method that returns either of these three methods

The generic Func works as follows:
The last datatype that you define in Func - "output" in this case should be the return type of the method which you are going to that particular function and the method should also be static.
This might help:
Func<LogInType, string> Login = LoginMethod;
private static string LoginMethod(LogInType loginType)
{
if (loginType == LogInType.Facebook)
return "Facebook";
if (loginType == LogInType.GooglePlus)
return "GooglePlus";
if (loginType == LogInType.UserNameAndPassword)
return "UserNameAndPassword";
return "Default";
}
The return type in the above example is string just for explaining.

Related

How to stop a function midway and let the caller performs some tasks, get the result and proceed with rest of the function's job in C#

My current scenario is that, I am writing a library in C# that performs some task. But the tasks will need to run first, then halfway, it needs some input from the caller before it can continue with the rest of the tasks in the same function. How can I achieve this sort of scenario as I am not sure what is the keyword that I should search for.
For example in the library there is a function:
public bool DoSomething()
{
SomeWorkToBeDoneByLibrary_1();
SomeWorkToBeDoneByLibrary_2();
SomeWorkToBeDoneByLibrary_3();
// the caller now needs to perform a job and return a result before the library function can proceed
// the caller is the application consuming the library
string result = SomeWorkToBeDoneByCaller(); // ***How to achieve this?
SomeWorkToBeDoneByLibrary_4(result);
SomeWorkToBeDoneByLibrary_5(result);
SomeWorkToBeDoneByLibrary_6(result);
return true;
}
You could pass in a Func<string>callback parameter:
public bool DoSomething(Func<string> someWorkToBeDoneByCaller)
{
SomeWorkToBeDoneByLibrary_1();
SomeWorkToBeDoneByLibrary_2();
SomeWorkToBeDoneByLibrary_3();
// the caller now needs to perform a job and return a result before the library function can proceed
// the caller is the application consuming the library
string result = someWorkToBeDoneByCaller();
SomeWorkToBeDoneByLibrary_4(result);
SomeWorkToBeDoneByLibrary_5(result);
SomeWorkToBeDoneByLibrary_6(result);
return true;
}
Then the call would look like:
libobj.DoSomething(() => "foo");
or
libobj.DoSomething(MyFunc);
string MyFunc() { return "foo"; }
More about Func<T> here: https://learn.microsoft.com/en-us/dotnet/api/system.func-1
There are a few ways to achieve this. One is to feed the caller into the method
public bool DoSomething(MyClass callerClass)
{
SomeWorkToBeDoneByLibrary_1();
SomeWorkToBeDoneByLibrary_2();
SomeWorkToBeDoneByLibrary_3();
string result = callerClass.SomeWorkToBeDoneByCaller();
SomeWorkToBeDoneByLibrary_4(result);
SomeWorkToBeDoneByLibrary_5(result);
SomeWorkToBeDoneByLibrary_6(result);
return true;
}
I've used the above pattern for a few things, depending on your use case it can do the trick (depending on the nature of the work I'd reccomend making it async too but that's a whole other thing)
Another way is to pass in delegate methods (change the <> arguments to change the method's signature, and use Action if the method returns void)
public bool DoSomething(Func<ReturnClass,string,string> methodFromCallerClass)
{
SomeWorkToBeDoneByLibrary_1();
SomeWorkToBeDoneByLibrary_2();
SomeWorkToBeDoneByLibrary_3();
string result = methodFromCallerClass("foo","Bar");
SomeWorkToBeDoneByLibrary_4(result);
SomeWorkToBeDoneByLibrary_5(result);
SomeWorkToBeDoneByLibrary_6(result);
return true;
}
and you can use linq to make passing in the delegate easier if the signatures don't match 100% something like (x,y) => Foo(x,y,"bar") changes the method from having three parameters to two

Can you pass generic delegate without the type parameter?

I have three projects
MVC Web application
Service application which is kind of two layers business/repository
Entity framework (all EF configuration lives here)
MVC references > service
Service references > EF
I have these three methods currently that do some work.
public bool StoreUpload<T>(UploadInformation information)
where T : class, IUploadEntity { }
public bool RemoveUpload<T>(UploadInformation information)
where T : class, IUploadEntity { }
public bool CommitUpload<T>(UploadInformation information)
where T : class, IUploadEntity { }
I call these three methods from my controller using these interfaces which delegate to the work methods above:
Boolean StoreUpload(UploadInformation information);
Boolean RemoveUpload(UploadInformation information);
Boolean CommitStoredDocuments(UploadInformation information);
Based on a condition from UploadTypes enumeration in a switch I call the correct work method. I do this because I don't want my mvc project to have access to the EF database types otherwise I know someone is going to start querying data from all over the application. I use these switch statements for all interfaced methods:
public bool StoreUpload(UploadInformation information)
{
switch (information.Type)
{
case UploadTypes.AutoIncident:
return RemoveUpload<AutoIncident>(information);
case UploadTypes.Incident:
return RemoveUpload<IncidentInjury>(information);
case UploadTypes.Inspection:
return RemoveUpload<Inspection>(information);
case UploadTypes.OtherIncident:
return RemoveUpload<OtherIncident>(information);
default:
return false;
}
}
public bool RemoveUpload(UploadInformation information) { ... }
public bool CommitStoredUpload(UploadInformation information) { ... }
This method might shed a little light on what the types parameters are being used for. I am updating tables in a generic way using EF.
private bool CommitStoredDocuments<T>(UploadInformation information) where T : class, IUploadEntity
{
var uploads = GetStoredUploads(information.UniqueId);
var entity = db.Set<T>().Include(e => e.Uploads)
.Single(e => e.UniqueId == information.UniqueId);
entity.Uploads.AddRange(uploads);
...
}
It would be nice to be able to pass the work method which requires a type parameter as a delegate to the switch work method calls.
public bool DoSomeWork(delegateMethod, information) {
switch(information.Type) {
case UploadTypes.AutoInciden:
return delegateMethod<AutoIncident>(information);
...
}
}
Can this be done?
Also, I had trouble constructing a good title for this question so please comment if these is a better way to describe the challenge.
It cannot be done directly due to several reasons.
First of all, as you probably noticed, delegateMethod<FooBar>(information) simply does not compile. This is because in your example the delegateMethod is a local variable (method parameter actually, but still a variable), and you cannot apply "type arguments" <FooBar> to a variable - you can apply them only on an identifier that indicates a (generic) type or a (generic) method.
Second reason is more interesting. When you pass a method as a delegate, the delegate actually catches the whole method signature, including all parameter types.
void Blah<T>(UploadInformation information){ ... }
var one = new Action<int>(Blah); // -> Blah<int>
var two = new Action<float>(Blah); // -> Blah<float>
var thr = new Action<andsoon>(Blah); // -> Blah<andsoon>
MagicDoSomeWork(one, ...); // these all
MagicDoSomeWork(two, ...); // delegates are already bound
MagicDoSomeWork(thr, ...); // and remember their concrete T
You need to actually specify the type for the Action so a proper version of generic method will be picked from a general description called Blah. These delegates are bound to concrete versions of the method and will accept only that types. These delegates are 'closed' in terms of their type arguments. Using normal ways, the MagicDoSomeWork will simply have no way of altering the T which these delegates already have remembered.
That two things are a kind of show stoppers, since by normal code only, you cannot write things like
var nope1 = new Action(Blah); // ctor for Action NEEDS type parameter
since Action constructor simply requires a type parameter. And once you pass any, it will lock the Blah type arguments
Also you cannot use open delegates:
var nope1 = new Action<>(Blah); // can't use empty <> in this context :(
since new operator requires a full type to create an object.
However, with a bit of reflection voodoo, it is possible to analyze and build a generic type or a generic method dynamically.
// first, build the delegate in a normal way
// and pick anything as the type parameters
// we will later replace them
var delegateWithNoType = new Action<object>(Blah);
// delegate has captured the methodinfo,
// but uses a stub type parameter - it's useless to call it
// but it REMEMBERS the method!
// .... pass the delegate around
// later, elsewhere, determine the type you want to use
Type myRealArgument;
switch(..oversomething..)
{
default: throw new NotImplemented("Ooops");
case ...: myRealArgument = typeof(UploadTypes.AutoIncident); break;
...
}
// look at the delegate definition
var minfo = delegateWithNoType.Method;
var target = delegateWithNoType.Target; // probably NULL since you cross layers
var gdef = minfo.GetGenericDefinition();
var newinfo = gdef.MakeGenericMethod( myRealArgument );
// now you have a new MethodInfo object that is bound to Blah method
// using the 'real argument' type as first generic parameter
// By using the new methodinfo and original target, you could now build
// an updated delegate object and use it instead the original "untyped" one
// That would be a NEW delegate object. You can't modify the original one.
// ...but since you want to call the method, why don't use the methodinfo
UploadInformation upinfo = ... ;
newinfo.Invoke(target, new object[] { upinfo });
// -> will call Blah<UploadTypes.AutoInciden>(upinfo)
word of warning: this is a sketch to show you how the delegate.Method/Target and methodinfo and getgenericdefinition and makegenericmethod work. I wrote it from memory, never compiled, never ran. It can contain minor typos, overlooked things and invisible rainbow unicorns. I didn't noticed any. Probably because they were invisible.
You can do it like this
public bool Invoke(EntityType entityType, ActionType action, Object[] arguments)
{
var actionType = Enum.GetName(typeof(ActionType), action);
var type = GetType();
var method = type.GetMethods().Single(m => m.IsGenericMethod && m.Name == actionType);
switch (entityType)
{
case EntityType.IncidentInjury:
var genericMethod = method.MakeGenericMethod(typeof(IncidentInjury));
return (bool)genericMethod.Invoke(this, arguments);
default:
return false;
}
}
The enum will just be a list of methods that I want to invoke this way and I create a base class for my services so I don't have to pass the instance to the Invoke method.
Instead of using delegates, consider using an interface (or abstract class). This way, your methods can retain their generic nature.
For example, if you create an interface like:
interface IUploadAction
{
bool Perform<T>(UploadInformation information)
where T : class, IUploadEntity;
}
Note that the T is not exposed in the type, it's only on the method. This is the key part.
Now you can implement this for your database methods:
class CommitStoredDocuments : IUploadAction
{
public bool Perform<T>(UploadInformation information)
where T : class, IUploadEntity
{
var uploads = GetStoredUploads(information.UniqueId);
var entity = db.Set<T>().Include(e => e.Uploads)
.Single(e => e.UniqueId == information.UniqueId);
entity.Uploads.AddRange(uploads);
//...
}
}
Your switching/dispatching method can look like this:
public bool DoAction(IUploadAction action, UploadInformation information)
{
switch (information.Type)
{
case UploadTypes.AutoIncident:
return action.Perform<AutoIncident>(information);
case UploadTypes.Incident:
return action.Perform<IncidentInjury>(information);
case UploadTypes.Inspection:
return action.Perform<Inspection>(information);
case UploadTypes.OtherIncident:
return action.Perform<OtherIncident>(information);
default:
return false;
}
}
And then you can write something like:
IUploadAction storeUpload;
public bool StoreUpload(UploadInformation information) => DoAction(storeUpload, information);

Pattern to reuse logic regardless of number of parms

I have some logging logic I want to call before and after several methods. Each method accepts different number/type of parameters. I'm trying to set it up so I don't have to duplicate the logging logic when I call each method. I've been able to reduce the amount of duplication by creating some delegates. I've created a delegate for each number/type of parms used and I have a method that accepts each delegate and does the logging. However, I still have around 6 different delegates and so the logic is duplicated for those six.
I think there is away to modify this so regardless of the number of parms, I have one method that does the logging and calls the method. But I haven't been able to figure it out.
Below is an example of one of the delegates and the logic I'm trying not to duplicate.
public delegate void LineOfBusinessHandler(DateTime runDate, LineOfBusinessCode lineOfBusinessCode);
public void Run(DateTime runDate, ProcessCode process, LineOfBusinessCode lineOfBusinessCode, LineOfBusinessHandler del)
{
this.ProcessManager.AddToBatchLog(process.ToString(), ProcessStatus.Started.ToString(), null, runDate);
try
{
del(runDate, lineOfBusinessCode);
this.ProcessManager.AddToBatchLog(process.ToString(), ProcessStatus.Finished.ToString(), null, runDate);
}
catch (Exception e)
{
int errorId = SystemManager.LogError(e, process.ToString());
this.ProcessManager.AddToBatchLog(process.ToString(), ProcessStatus.Errored.ToString(), errorId, runDate);
}
}
I realize this maybe beyond the scope and/or the capabilities of what you're looking for. But if you have a generic logging logic that you want to reuse over different method calls, without losing typesafety (i.e. NOT passing your arguments around in object[]) the way to go is interception. You need a framework (I don't recommend writing your own at first!) that can provide AOP, Dependency Injection or something similiar. Those things can usually deal with interception.
For example I have a logging interceptor I use with Ninject:
public void Intercept(IInvocation invocation)
{
var logger = LoggerFactory.GetLogger(invocation.Request.Method.DeclaringType);
var debug = !invocation.Request.Method.IsSpecialName && logger.IsDebugEnabled;
if (debug)
logger.Debug(invocation.Request.Method.Name);
try
{
invocation.Proceed();
if (debug)
logger.Debug(invocation.Request.Method.Name + " FINISH");
}
catch (Exception)
{
logger.Error(invocation.Request.Method.Name + " ERROR");
throw;
}
}
Then I create my objects by getting them with Ninject (if you don't know about it, check out some tutorials), while adding some Interception to them, for example: Kernel.Bind<MyTypeToLog>().ToSelf().Intercept().With<LoggingInterceptor>(); where LoggingInterceptor implements IInterceptor with the method shown above...
Just say if you need more in details help!
EDIT: just realized that my example doesn't show this, but you can access the arguments (as an object collection though) of the invocation too!!
It depends on what is common among the different versions, but assuming runDate and process are common you could do something like this:
public void Run(DateTime runDate, ProcessCode process, LineOfBusinessCode lineOfBusinessCode, LineOfBusinessHandler del)
{
this.DoRun(runDate, process, (d, p) => del(d, p, lineOfBusinessCode));
}
public void DoRun(DateTime runDate, ProcessCode process, Action<DateTime, ProcessCode> action)
{
this.ProcessManager.AddToBatchLog(process.ToString(), ProcessStatus.Started.ToString(), null, runDate);
try
{
action(runDate, process);
this.ProcessManager.AddToBatchLog(process.ToString(), ProcessStatus.Finished.ToString(), null, runDate);
}
catch (Exception e)
{
int errorId = SystemManager.LogError(e, process.ToString());
this.ProcessManager.AddToBatchLog(process.ToString(), ProcessStatus.Errored.ToString(), errorId, runDate);
}
}
You can even generalize so you don't have do define custom delegates as this:
public void Run<T1>(DateTime runDate, ProcessCode process, T1 param1, Action<DateTime, ProcessCode, T1> del)
{
this.DoRun(runDate, process, (d, p) => del(d, p, param1));
}
public void Run<T1, T2>(DateTime runDate, ProcessCode process, T1 param1, T2 param2, Action<DateTime, ProcessCode, T1, T2> del)
{
this.DoRun(runDate, process, (d, p) => del(d, p, param1, param2));
}
The C# language doesn't have any syntax for metaprogramming. You'll have to use reflection. You certainly can reflect against an arbitrary method/delegate to determine the parameter types, then build a method that logs parameters and calls the original method, compile this new wrapper method, and return a delegate with the same call signature as the original.
You can do this at runtime (return a delegate) or build a new assembly with all the wrapper functions, that can then be referenced by your code and used normally.
You should look at the code-weaving tools used for Aspect-Oriented-Programming. Some of them already do this.
Unlike using a params array, this gives you a wrapper with the same signature (or delegate type) as the original method, so it is type safe and Intellisense works (as much as for any other delegate).
If I understand your question correctly it sounds like you could use the C# params keyword. See this for a reference on how to use it: http://msdn.microsoft.com/en-us/library/w5zay9db.aspx
One of the requirements when using params is that it has to be placed last in the signature of the function. Then, inside of the function you can enumerate and iterate over the variable parameters list as if it were an array.
EDIT
To expand on a comment posted by #Ben Voigt, another limitation of using the params keyword is that it requires the variable parameter list to be of the same type. This however can be mitigated in your case since all you care about is logging. In this case presumably you would be invoking the ToString() method on the objects you need to log so you could make the variable parameters list of type object.
In case calling the ToString() is not enough and you have different types of objects you could make all these objects implement a common interface. Let's call it ILoggableObject which exposes a method to provide the logging output. That's if you have the ability to change those objects.

C# Delegates & guid.newguid()

I just started using C# this afternoon, so be a little gentle.
Currently I am working on a type of "template engine" where one of the callbacks needs to generate a globally unique ID. I am using delegates to manage the callbacks.
Currently the code looks like this (though I have also tried an anonymous function & returning NewGuid directly w/o a variable):
static string UID(List<string> p)
{
string s = Guid.NewGuid().ToString();
return s;
}
Which, when called directly, works fine. However if I try to call it via the delegate (added to a StringDictionary via addCallback("generate UID", new CallbackWrapper(UID))), the program will generate the same GUID regardless of how many times I duplicate it; even though calling the method directly both before & after the event occurs results in a unique ID as expected. I'v
No doubt it's just something simple I've missed, inevitably stemming from me being relatively inexperienced at C#.
Any help would be appreciated.
Thanks.
Well, I've now tried Dictionary with the same result.
CallbackWrapper is just the delegate, it's defined like this:
delegate string CallbackWrapper(List<string> parameters);
The remainder of the work is done in another class, which looks like this:
class TemplateParser
{
private Dictionary<string, CallbackWrapper> callbackMap;
public TemplateParser(string directivePrefix, string directiveSuffix)
{
...
callbackMap = new Dictionary<string,CallbackWrapper>();
}
public TemplateParser() : this("<!-- {", "} -->") {}
{
callbackMap.Add(name, callback);
}
public string parse(string filename)
{
...
string replacement =
callbackMap[directiveName](new List<string>(parameters.Split(new string[] { ";", " " }, StringSplitOptions.RemoveEmptyEntries));
...
}
}
I've stripped out the majority of the string handling code to save some space.
The issue is in your calling code, not in the code itself, nor in the delegate.
Using delegates here definitely works if called correctly.
Furthermore, your code can be slightly simplified:
static string UID(List<string> p)
{
return Guid.NewGuid().ToString();
}
(The variable is utterly redundant.)
use delegate.invoke
The difference between direct function call and delegate.invoke is here
http://social.msdn.microsoft.com/Forums/en/csharplanguage/thread/f629c34d-6523-433a-90b3-bb5d445c5587
StringDictionary will automatically cast your CallbackWrapper to a string, meaning it will only run once and store the output of CallbackWrapper.ToString(). This is probably not what you want.
Try using Dictionary<string, CallbackWrapper> instead.

Redirect method call within delegate

I have a protected method in a base class which accepts a Func<T> and then turns around and executes with some added goodness. Example usage:
public MyResponse DoSomething(MyRequest request)
{
return base.Execute(() => this.Channel.DoSomething(request));
}
What I'm looking to do is take the func delegate instance and redirect the method call in the expression to another instance besides this.Channel, so something like:
protected TResponse Execute<TResponse>(Func<TResponse> command)
{
return command.Method.Invoke(this.otherInstanceOfChannel, command.Target);
}
Here the "this.otherInstanceOfChannel" would be an instance of a different concrete class than the "this.channel" passed in the original call but implements the same interface. I just need to figure out what method is being called and execute that on another instance passing in the original arguments from the caller. I started down the path of MethodCallExpressions and the like but my expression-foo is weak...
Edited/rewrote for clarity - hope this version makes more sense.
Thanks,
Matt
Yes you can do this. No time right now to give you the full solution but here is a skeleton of what you would do:
protected TResponse Execute<TResponse>(Expression<Func<TResponse>> command)
{
// Check that the expression is in the correct format (ie you are calling a method off of a type Channel
// Get the name of the method call. Something like:
var node = expr.Body as MemberExpression;
if (object.ReferenceEquals(null, node))
throw new InvalidOperationException("Expression must be of member access");
var methodName = node.Member.Name;
// Use reflection to invoke methodName on otherInstanceOfChannel
// Cast the results to TResponse and return
}
As you can see the only real trick is the use of Expression<>. The type change is transparent to any client code - they don't have to change at all. Here is some code to get you started with parsing expression trees.
I believe that you can provide the instance in the lambda expression like so:
IMyChannel myChannelInstance = MyChannelInstanceFactory.Create();
Execute(() => myChannelInstance.DoSomething(request))
If this can not be done with lambda expressions and I am sure they can you can change this to a delegate and it would work fine. The lambda expression is pointing to a code execution block and as such you can put whatever matches the expression arguments in that code block.

Categories