I've used delegates in the past so I'm familiar with their use and benefits. I've also done a lot of reading/research, but I'm trying to wrap my head around this and getting nowhere. I'd like to use a delegate (I believe) to encapsulate some code or use a delegate within a method to call some outside code.
I'm using the same code in 20 different places to wrap an entity framework update in a transaction. I would like the code in one place; however, I can't do it in a method by itself because there is a middle part that will change each time. I'm looking for some ideas / clarification on how I can best do this (.net 3.5, ms sql 2010). - thnx
code sample:
void AddItem(string objDetails)
{
// setup method specific entity objects
SomeObject obj = new SomeObject { Details = objDetails };
//////// Begin transaction code that I would like to encapsulate ///////
bool success = false;
using (Entities data = new Entities())
{
for (int i = 0; i < s.BaseSettings.CommandRetries; i++)
{
using (TransactionScope transaction = new TransactionScope())
{
try
{
//////////////////////////////////////////////////////////////
///////// BEGIN Code that I would like to change / call different each time ////////
data.AddToSOMEOBJECTs(obj);
//////////////// END //////////////////////////////////
//// RETURN TO ENCAPSULATED CODE ////
data.SaveChanges(false);
transaction.Complete();
success = true;
break;
}
catch (Exception ex)
{
if (ex.GetType() != typeof(UpdateException))
{
throw new Exception("Unhandled db exception.");
}
}
}
}
if (success)
{
data.AcceptAllChanges();
}
else
{
throw new Exception();
}
}
}
You pass the function a delegate (or lambda) that does the custom bit
like this
void AddItem<T>(string objDetails, Func<T> custom) {
.
. common
.
.
T someReturn = custom();
.
. common
.
}
add call like this perhaps:
Func<int> custom = () => {
// do something custom
return 9;
}
// Call common function
AddItem<int>(..., custom);
All that matters is that the interface for the Func matches what you need.
You can pass different methods by using a delegate and an event. Here's an example of a class that does this:
class SampleClass
{
public delegate void TransactionDelegate();
public event TransactionDelegate MyTransactionDelegate;
public void DoSomething()
{
MyTransactionDelegate();
}
}
You can then use a lambda expression to pass methods to the event like this:
class MainClass
{
public static void Main (string[] args)
{
var test = new SampleClass();
test.MyTransactionDelegate += () => {Console.WriteLine("Success");};
test.DoSomething();
}
}
Related
I can't seem to figure out why this is throwing "Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type." Specifically this part method.CreateDelegate(eventInfos[0].EventHandlerType, new Commands());
//These are defined at the top of the class
public delegate Task MessageReceivedAsyncDelegate(SocketMessage arg);
public delegate void MessageReceivedDelegate(SocketMessage arg);
public event MessageReceivedAsyncDelegate MessageReceivedCommandAsync;
public event MessageReceivedDelegate MessageReceivedCommand;
//These are defined at the top of the class
Type B = typeof(Base);
Type C = typeof(Commands);
MethodInfo[] methods = C.GetMethods();
foreach (MethodInfo method in methods)
{
EventInfo[] eventInfos = B.GetEvents();
if(method.GetCustomAttributes(typeof(SubscribeToMessageRecivedAttribute)).Any()
{
if (method.ReturnType == typeof(Task))
{
try { eventInfos[0].AddEventHandler(C, method.CreateDelegate(eventInfos[0].EventHandlerType, new Commands())); }
catch(Exception exception) { Console.WriteLine(exception); }
}
else eventInfos[1].AddEventHandler(C, method.CreateDelegate(eventInfos[1].EventHandlerType, new Commands()));
}
}
Method which it's trying to add
public partial class Commands : ModuleBase<SocketCommandContext>
{
[SubscribeToMessageRecived]
public static async Task Mock(SocketMessage arg)
{
Console.WriteLine("Mocking");
if (Base.mockList.Contains((int)arg.Author.Id))
{
char[] msgArray = arg.Content.ToCharArray();
for (int i = 0; i < arg.Content.Length; i++)
{
if (DaMef.RandomRange(0,3) == 1) msgArray[i] = msgArray[i].ToString().ToLower().ToCharArray()[0];
else msgArray[i] = msgArray[i].ToString().ToUpper().ToCharArray()[0];
}
string finalString = msgArray.ToString();
await arg.Channel.SendMessageAsync(finalString + "\nhttps://imgur.com/a/HsiBmYc");
}
}
}
I'm trying to subscribe all methods in the Commands with "SubscribeToMessageRecivedAttribute" to an event.
There are answers online but none seem to be it. (Or maybe I just didn't understand them.) I've never used reflections and have barely used events so sorry if it's something stupid.
Now I have a ConcurrentDictionary .
I want to invoke the IDataExchangeServiceCallBack's method.
the IDataExchangeServiceCallBack's code below:
[ServiceContract]
public interface IDataExchangeServiceCallBack
{
[OperationContract(IsOneWay = true)]
void SendResult(string msg);
[OperationContract(IsOneWay = true)]
void Receive(List<RealDataModel> models);
}
In other class, I want invoke dict's method foreach.
such as
public void Receive(List<RealDataModel> models)
{
Broast(o => nameof(o.Receive), models);
}
public void SendResult(string msg)
{
Broast(o => nameof(o.SendResult), msg);
}
And Broast method below:
private void Broast(Func<IDataExchangeServiceCallBack, string> funcMethodName, params object[] args)
{
if (_callbackChannelList.Count > 0)
{
var callbackChannels = _callbackChannelList.ToArray();
foreach (var channel in callbackChannels)
{
try
{
var type = channel.Value.GetType();
// fetch the method's name.
var methodName = funcMethodName.Invoke(channel.Value);
// reflect & get the method
var methodInfo = type.GetMethod(methodName);
//invoke
methodInfo?.Invoke(channel.Value, args);
}
catch (Exception ex)
{
_callbackChannelList.TryRemove(channel.Key, out _);
}
}
}
}
Now my question is how to implement above code without reflect, it's there any better solution.
The Expression can implement it ?
I'm not familiar with Expression.
Thanks.
I don't understand how you got to the solution you have. Regardless of the type of o, the expression, for example, nameof(o.Receive) will always result in the string "Receive". It seems to me you could just pass nameof(IDataExchangeServiceCallBack.Receive) to the method instead of passing a delegate.
That said, I also don't understand why you are looking to use reflection or Expression. It appears to me that, at the call site, you know the type of object you're dealing with, the method you want to call, and the arguments you want to pass. So you could just pass a delegate that does all that. For example:
private void Broast(Action<IDataExchangeServiceCallBack> callback)
{
foreach (var channel in _callbackChannelList.ToArray())
{
try
{
//invoke
callback(channel.Value);
}
catch (Exception ex)
{
_callbackChannelList.TryRemove(channel.Key, out _);
}
}
}
Used like:
public void Receive(List<RealDataModel> models)
{
Broast(o => o.Receive(models));
}
public void SendResult(string msg)
{
Broast(o => o.SendResult(msg));
}
Note that I've cleaned up the Broast() method a bit. There's very little overhead calling ToArray() on an empty collection, and it simplifies the code significantly to remove the Count > 0 check. Code is always easier to write and read later if you can remove unnecessary conditional checks.
I have a very ugly piece of code that is scattered throughout a project. The only difference in this piece of code is one line where a different method is called. The method that's called always returns a bool.
I want to refactor this and extract it into its own method and pass the 1 liner into this method (if possible) from my understanding I can use a Func<> to do this.
Here is what I am trying to do. I have tried to keep things as clear as possible
public async Task<bool> SomeMethod()
{
//code removed for readability.
//IsCustomerComplete will return a bool
var process = await RepeatableMasterPiece(1, 2, _myRepo.IsCustomerComplete(someParameterRequired));
//do something with process result
return process;
}
private async Task<bool> RepeatableMasterPiece(int param1, int param2, Func<Task<bool>> method)
{
int retry = 0;
bool soapComplete = false;
string soapFault = "just a placeholder for example";
bool blackListStatus = false;
while (!soapComplete && retry <= 1)
{
try
{
if (soapFault != null)
{
//do some stuff with param1 & param2 here
}
if (!soapComplete)
{
return await method.Invoke();
}
}
catch (FaultException ex)
{
soapFault = ex.Message;
retry++;
if (retry > 1)
{
throw ex;
}
}
}
}
From the repo
public async Task<bool> IsCustomerComplete(int id)
{
...removed other code here
return true;
}
Does this make sense, am I on the right track, from the examples I have found they only show Funcs<> passing in a string or int which makes things look a whole lot simpler.
If I understand your goal, you're very close. The biggest thing you're missing is the conversion of your method to a Func<> delegate. In your question, you included the argument parentheses. You don't need these if you're not invoking the method.
So, basically, this is what you probably want.
var process = await RepeatableMasterPiece(1, 2, _myRepo.IsCustomerComplete);
Here is an example based on your provided details.
public async Task SomeMethod() {
//code in method.
var _myRepo = new repo();
var someParameterRequired = 1;
var process = await RepeatableMasterPiece(1, 2, () => _myRepo.IsCustomerComplete(someParameterRequired));
//do something with process result
}
private async Task<bool> RepeatableMasterPiece(int param1, int param2, Func<Task<bool>> method) {
int retry = 0;
bool soapComplete = false;
string soapFault = "just a placeholder for example";
bool blackListStatus = false;
while (!soapComplete && retry <= 1) {
try {
if (soapFault != null) {
//do some stuff with param1 & param2 here
}
if (!soapComplete && method != null) {
return await method();
}
} catch (FaultException ex) {
soapFault = ex.Message;
retry++;
if (retry > 1) {
throw ex;
}
}
}
return false;
}
The assumption here is that all the target methods will be returning Task<bool>
If the target function does not require any parameters then you can do as mentioned in other answer and just provide the function itself without the parenthesis.
I would checkout Action<T> and Func<T, TResult> delegates.
Use an Action<T> delegate when you wish to pass in an void anonymous method.
Use an Func<TResult> delegate when you need to pass in a anonymous method with a return type.
MSDN has some good examples:
Func Delegates MSDN
Action Delegates MSDN
I have used actions and function many times over my career. They come in handy when adding features to tightly coupled code that cannot be refactored.
However, their correct usage should be used when writing loosely coupled code. There are many times where I wanted to give the implementer the option to provide their own functionality.
I'm working on a framework in C# that will depend on pluggable components implemented as classes inheriting a base class. In order to make the components as simple as possible, I am working on some weird control flow.
The base class includes a static method RunStep(parameter). This method is called a number of times by the inheriting class, and each time it is called a condition is checked. If this condition happens to be false, I want the calling method to stop and return. A simplified working version of the code would be:
Base class:
class MyBase
{
private static object RunStep(string parameter)
{
if(SomeFunction(parameter))
return SomeOtherFunction(parameter);
else
return null;
}
}
Inheriting class:
class MyInheritor
{
public void Run()
{
object result = RunStep("mystring1");
if(null != result)
{
//perform some logic on result
result = RunStep("mystring2");
if(null != result){
//perform some different logic on result
RunStep("mystring3");
}
}
}
}
What I am wondering is whether it is possible to do something in the base class so that I can simplify the inheriting class to this:
class MyInheritor2
{
public void Run()
{
object result = RunStep("mystring1");
//perform some logic on result
result = RunStep("mystring2");
//perform some different logic on result
result = RunStep("mystring3");
}
}
}
I would put the parameters in a list and loop over them, but there is logic that needs to happen after each call to the RunStep method, and the logic is different each time. This takes a loop off the table. Also note that the logic between the RunStep calls accesses properties on result, so it crashes without the null checks.
It may seem like a trivial thing, but there may be thousands of these Inheriting classes and simplifying them is a big deal.
Let the base class to control the execution flow:
class Base
{
private readonly List<Tuple<string, Action>> steps = new List<Tuple<string, Action>>();
protected void RegisterStep(string parameter, Action someLogic)
{
steps.Add(Tuple.Create(parameter, someLogic));
}
protected void Run()
{
foreach (var step in steps)
{
var result = RunStep(step.Item1);
if (result == null)
{
break;
}
// perform some logic
step.Item2();
}
}
private object RunStep(string parameter)
{
// some implementation
return null;
}
}
class Derived : Base
{
public Derived()
{
RegisterStep("1", () => { });
RegisterStep("2", () => { });
RegisterStep("3", () => { });
// etc
}
}
There's no way to make a function call exit the calling function except for throwing an Exception, which you shouldn't do.
What you can do to make your code cleaner is to invert the cases.
object result = RunStep("mystring1");
if (result == null) return;
result = RunStep("mystring2");
if (result == null) return;
result = RunStep("mystring3");
if (result == null) return;
I have class with many methods:
public class A {
public string method1() {
return "method1";
}
public string method2() {
return "method2";
}
public string method3() {
return "method3";
}
.
.
.
public string methodN() {
return "methodN";
}
}
I would like to add call to doSomething() in each method, for example:
public string methodi() {
doSomething();
return "methodi";
}
What is the best way to do so? Is there any suitable design pattern?
This is a typical use case for AOP (aspect oriented programming). You'd define the insertion points for the method calls and the AOP engine adds the correct code to the class file. This is often used when you want to add log statements without cluttering your source files.
For java you could add the aspectj library
For C# and .NET have look at this blog. Looks like a good starter.
Using AOP is already a good answer, it was my first idea too.
I tried to figure out a good way doing it without AOP though and came up with this idea (using the Decorator pattern):
interface I {
String method1();
String method2();
...
String methodN();
}
class IDoSomethingDecorator implements I {
private final I contents;
private final Runnable commonAction;
IDoSomethingDecorator(I decoratee, Runnable commonAction){
this.contents = decoratee;
this.commonAction = commonAction;
}
String methodi() {
this.commonAction().run();
return contents.methodi();
}
}
You could then decorate the construction of A (which implements I):
I a = new IDoSomethingDecorator(new A(),doSomething);
It is basically no rocket science and in fact results in more code than your first idea, but you are able to inject the common action and you separate the additional action from the class A itself. Further, you can turn it off easily or use it only in tests, for instance.
Why not having a single function?
public string methodi(int i) {
doSomething();
return "method" + i.toString();
}
Or you may write a function which takes an Func parameter and call this function instead of your functions.
public string Wrapper(Func<string> action)
{
doSomething();
return action();
}
and call your functions from this function;
string temp = Wrapper(method1);
You could use reflection.
public String callMethod(int i) {
doSomething();
java.lang.reflect.Method method;
try {
method = this.getClass().getMethod("method" + i);
} catch (NoSuchMethodException e) {
// ...
}
String retVal = null;
try {
retVal = method.invoke();
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) { }
return retVal;
}