How to invoke a method from a workflow in WF 4? - c#

I would like to invoke a simple method (no arguments, returns void) from within a workflow. Suppose I have the following class:
public class TestClass
{
public void StartWorkflow()
{
var workflow = new Sequence
{
Activities =
{
new WriteLine { Text = "Before calling method." },
// Here I would like to call the method ReusableMethod().
new WriteLine { Text = "After calling method." }
}
}
new WorkflowApplication(workflow).Run();
}
public void ReusableMethod()
{
Console.WriteLine("Inside method.");
}
}
How do I call ReusableMethod from within my workflow? I was looking at InvokeAction but that doesn't seem to be what I want. I could also write a custom activity that calls this method, but I'm specifically interested in this scenario. Is this possible?

How about InvokeMethod ?
public class TestClass
{
public void StartWorkflow()
{
var workflow = new Sequence
{
Activities =
{
new WriteLine {Text = "Before calling method."},
// Here I would like to call the method ReusableMethod().
new InvokeMethod {MethodName="ReusableMethod", TargetType = typeof(TestClass)},
new WriteLine {Text = "After calling method."}
}
};
var wf = new WorkflowApplication(workflow);
wf.Run();
var are = new AutoResetEvent(false);
wf.Completed = new Action<WorkflowApplicationCompletedEventArgs>(arg => are.Set());
are.WaitOne(5000);
}
public static void ReusableMethod()
{
Console.WriteLine("Inside method.");
}
}

Related

Passing an Action, Func or delegate to a public method or constructor is a security issue

I heard that passing an action, function or delegate to a public method is a security issue.
I want to understand why or how this can be exploited because I cannot find a way to do it.
At least.. is it a best practice to not pass delegates to classes?
Examples of so called vulnerable code:
Public constructor action:
public class MyClass { public MyClass(Action doSomething) { doSomething?.Invoke(); } }
with the calling code in another project using my code as a reference:
var securityIssueActionOutsideOfMyControl = new Action(() => { ... });
var instance = new MyClass(securityIssueActionOutsideOfMyControl);
Public constructor action with parameter:
public class MyClass
{
public MyClass(Action<string> doSomething)
{
doSomething?.Invoke("something");
}
}
with the calling code in another project using my code as a reference:
var securityIssueActionOutsideOfMyControl = new Action<string>((someParameter) => { ... });
var instance = new MyClass(securityIssueActionOutsideOfMyControl);
Same so called issue can happen with functions or delegates passed to public constructor.
Public method with action:
public class MyClass { public void MyAction(Action doSomething) { doSomething?.Invoke(); } }
with the calling code in another project using my code as a reference:
var securityIssueActionOutsideOfMyControl = new Action(() => { ... });
var instance = new MyClass();
instance.MyAction(securityIssueActionOutsideOfMyControl);
public class MyClass { public void MyAction(Action<string> doSomething) { doSomething?.Invoke("some string"); } }
with the calling code in another project using my code as a reference:
var securityIssueActionOutsideOfMyControl = new Action<string>((someParameter) => { ... });
var instance = new MyClass();
instance.MyAction(securityIssueActionOutsideOfMyControl);
Same so called issue can happen with functions or delegates passed to public methods.
How is it different than the following code using events?
var securityIssueActionOutsideOfMyControl = new Action(() => { ... });
var instance = new MyClass();
instance.MyEvent += (s, e) => securityIssueActionOutsideOfMyControl;
Or how it is different from calling the method directly in a different project?
var securityIssueActionOutsideOfMyControl = new Action(() => { ... });
securityIssueActionOutsideOfMyControl?.Invoke();

Observable class property doesn't trigger subscription

Simple observable variable works as expected an triggers callback immediately on the same thread.
Why a class variable of any observable type (Subject, ISubject, Observable, IObservable) doesn't trigger callback?
Example with simple variable - [Works]
var x1 = new Subject<string>();
var x2 = x1.DistinctUntilChanged();
x2.Subscribe(o =>
{
// Triggered as expected
});
x1.OnNext("Hello");
Example with a class - [Does NOT work]
public class InstrumentModel
{
public Subject<string> Demo => new Subject<string>();
}
var class1 = new InstrumentModel();
class1.Demo
//.DistinctUntilChanged()
//.SubscribeOn(Scheduler.CurrentThread)
//.ObserveOn(Scheduler.CurrentThread)
.Subscribe(o =>
{
// Never triggered
});
class1.Demo.OnNext("Hello");
Problem is that you made Demo to return new instance of Subject<string> every time it is used.
Demo instance that you subscribed too, is not the same instance you called OnNext() on.
class1.Demo.Subscribe(...); // makes new instance `Subject<string>`
class1.Demo.OnNext("Hello"); // makes another new instance of `Subject<string>`
Keep it the same instance and it will work. For example:
public class InstrumentModel
{
public Subject<string> Demo = new Subject<string>();
}
or:
public class InstrumentModel
{
public InstrumentModel()
{
this.Demo = new Subject<string>();
}
public Subject<string> Demo { get; }
}

MOQ - Why is below not mocking?

Anyone have any idea why below still calls YesService?
It almost seems like IYesService is considered separate to YesService..
Any ideas?
public interface IYesService
{
string Hello();
}
public class YesService : IYesService
{
public string Hello()
{
return "Yes";
}
}
class Program
{
static void Main(string[] args)
{
var _mock = new Mock<IYesService>();
_mock.Setup(x => x.Hello()).Returns("No");
var service = new YesService();
var result = service.Hello();
Console.Write(result);
Console.ReadLine();
}
}
Because you don't use the _mock, you instantiate the YesService and call the method on that.
You can use mocking when you consume this interface:
public class ServiceUser
{
private IYesService _yesService;
public ServiceUser(IYesService yesService)
{
_yesService = yesService;
}
public string CallService()
{
return _yesService.Hello();
}
}
Then use it like this:
var serviceMock = new Mock<IYesService>();
serviceMock.Setup(x => x.Hello()).Returns("No");
var service = new ServiceUser(serviceMock.Object);
var result = service.CallService();
You are creating an instance of YesService (the concrete class) in your Main method. The var service line an be done away with, and the var result line should become:
var result = _mock.Object.Hello();
Try that...

Derived public method in class

I'm trying to test with Microsoft Fakes code in a application which sort of the following construction in a library:
public static class C
{
public A GetConfigurationFactory(Uri uri);
}
public class A : B
{
public A(Uri uri)
{
}
}
public class B
{
public void Authenticate()
{
}
}
I've created the following test for this in Visual Studio:
//Arrange
ShimA.ConstructorUri = (#this, value) =>
{
var shim = new ShimA(#this);
};
ShimC.GetConfigurationFactory = (uri) =>
{
var shim = new A(uri);
return shim;
};
var uri1 = new Uri("http://test-url");
//Act
A.Authenticate()
I get a null pointer when I call the Authenticate method from instance A.
Does anyone how I can solve this? I already looked and there is no overloaded constructor.
Solved this problem with the following code:
ShimB.AllInstances.Authenticate = (someValue) => { return; }
This code ensures that when I call the Authenticate method from any class it will always return the specified value.

Pass a method to another method

I want to be able to specify a method in another method.
Something like
public class Binder
{
public void Bind(whatShouldIWriteHere?)
{
// do stuff with the MethodInfo
}
}
so that I can do:
public class A
{
public void DoIt(string tmp)
{
}
}
var binder = new Binder()
binder.Bind<A>(x => x.DoIt);
Instead of:
var method = typeof(A).GetMethod("DoIt");
binder.Bind(method);
Is that possible? :)
Pass the method as a delegate and use the Delegate.Method property.
In your case Binder.Bind would be like:
public void Bind(Delegate del)
{
var info = del.Method;
//Add your logic here.
}
And to pass a method to it:
var binder = new Binder();
var instance = new A();
binder.Bind(new Action<string>(instance.DoIt))

Categories