I am writing a proxy to access a WCF service where we have access to both the WCF service and the client's code.
For each method in the Service contract interface I am writing a method like this.
The trouble is that there are many methods in the interface and effectively this is turning into a copy and paste exercise.
Is there a more elegant way (with lambdas?) of doing this that isn't so verbose ? I can't quick figure it out please....
public interface IServiceContract
{
DataContracts.TypeA Method1(int arg1, string arg2);
string Method2(string arg1);
DateTime Method3();
int Method4(DataContracts.Input1);
// etc............
}
public class Proxy : IServiceContract....
public DataContracts.TypeA Method1(int arg1, string arg2)
{
IFileService proxy = null;
ChannelFactory<IFileService> factory = null;
try
{
factory = new ChannelFactory<IFileService>("*");
proxy = factory.CreateChannel();
return proxy.Method1(arg1, arg2);
}
finally
{
CloseConnection(proxy, factory);
}
}
public List<AnOtherResultPoco> Method2(string arg1)
{
IFileService proxy = null;
ChannelFactory<IFileService> factory = null;
try
{
factory = new ChannelFactory<IFileService>("*");
proxy = factory.CreateChannel();
return proxy.Method2(args1);
}
finally
{
CloseConnection(proxy, factory);
}
}
//ad inifinitum for methods,3,4,5...
If you want to factorize your code a bit using lambda, I suggest to write a method that looks like this:
...
public void ServiceCall(Action<IFileService> action)
{
IFileService proxy = null;
ChannelFactory<IFileService> factory = null;
try
{
factory = new ChannelFactory<IFileService>("*");
proxy = factory.CreateChannel();
return action(proxy);
}
finally
{
CloseConnection(proxy, factory);
}
}
So you call your service methods this way:
...
List<AnOtherResultPoco> result;
MyClass.ServiceCall(p => { result = p.Method2("hello"); });
...
You could use reflection.
public List<MyResultType> SearchBy(string searchTerm, string method)
{
IFileService proxy = null;
ChannelFactory<IFileService> factory = null;
try
{
factory = new ChannelFactory<IFileService>("*");
proxy = factory.CreateChannel();
if (!IsMethodAllowed(method))
{
throw new SecurityException();
}
return (List<MyResultType>)proxy.GetType().GetMethod(method).Invoke(proxy, new object[] { searchTerm });
}
finally
{
CloseConnection(proxy, factory);
}
}
This is another way, maybe what you are looking for.
public List<MyResultType> SearchByMethod1(int a, int b)
{
return (List<MyResultType>)SearchBy(new object[] { a, b }, "Method1");
}
public List<MyResultType2> SearchByMethod2(MyResultType b)
{
return (List<MyResultType2>)SearchBy(new object[] { b }, "Method1");
}
protected object SearchBy(object[] parameters, string method)
{
IFileService proxy = null;
ChannelFactory<IFileService> factory = null;
try
{
factory = new ChannelFactory<IFileService>("*");
proxy = factory.CreateChannel();
if (!IsMethodAllowed(method))
{
throw new SecurityException();
}
return (List<MyResultType>)proxy.GetType().GetMethod(method).Invoke(proxy, parameters);
}
finally
{
CloseConnection(proxy, factory);
}
}
This would not lead to having generics all over your code. It is neatly wrapped inside proxy.
I know its an old question, but I run into the same problem today, and found an easy solution, thought I would share for future users.
So in this solution, we will make our own proxy instead of generating a service reference.
Here is the Proxy, The idea is to make it generic:
public class Proxy<T>
{
public ChannelFactory<T> Channel { get; set; }
public Proxy()
{
Channel = new ChannelFactory<T>("endpoint");
}
public T CreateChannel()
{
return Channel.CreateChannel();
}
}
Now here is the trick :
For void methods :
public void Execute(Action<T> action)
{
T proxy = CreateChannel();
action(proxy);
((ICommunicationObject)proxy).Close();
}
For return:
public TResult Execute<TResult>(Func<T, TResult> function)
{
T proxy = CreateChannel();
var result = function(proxy);
((ICommunicationObject)proxy).Close();
return result;
}
Where the TResult is the returning type.
How to use:
Proxy<IService> proxy = new Proxy();
// for a void method
Proxy.Execute(prxy => prxy.Method());
// for non void method.
var result = Proxy.Execute(prxy => prxy.Method());
So, to sum up, here is how the proxy class should look like:
public class Proxy<T>
{
public ChannelFactory<T> Channel { get; set; }
public Proxy()
{
Channel = new ChannelFactory<T>("endpoint");
}
public T CreateChannel()
{
return Channel.CreateChannel();
}
public void Execute(Action<T> action)
{
T proxy = CreateChannel();
action(proxy);
((ICommunicationObject)proxy).Close();
}
public TResult Execute<TResult>(Func<T, TResult> function)
{
T proxy = CreateChannel();
var result = function(proxy);
((ICommunicationObject)proxy).Close();
return result;
}
}
I recommend this solution for a custom wcf proxy without using any service reference, its really simple and easy.
Related
I've got a setup like this with a concrete class that is instantiated inside the method I want to test. I want to mock this concrete class an not have it execute the code inside. Hence, no exception should be thrown:
public class Executor
{
public bool ExecuteAction(ActionRequest request)
{
switch (request.ActionType)
{
case ActionType.Foo:
var a = new Foo();
return a.Execute(request);
case ActionType.Bar:
var b = new Bar();
return b.Execute(request);
}
return true;
}
}
public class Foo
{
public virtual bool Execute(ActionRequest request)
{
throw new NotImplementedException();
}
}
public class Bar
{
public virtual bool Execute(ActionRequest request)
{
throw new NotImplementedException();
}
}
My NUnit test looks like this:
[Test]
public void GivenARequestToFooShouldExecuteFoo()
{
var action = new Mock<Foo>();
action.Setup(x => x.Execute(It.IsAny<ActionRequest>())).Returns(true);
var sut = new Mock<Executor>();
sut.Object.ExecuteAction(new ActionRequest
{
ActionType = ActionType.Foo
});
}
[Test]
public void GivenARequestToBarShouldExecuteBar()
{
var action = new Mock<Bar>();
action.Setup(x => x.Execute(It.IsAny<ActionRequest>())).Returns(true);
var sut = new Mock<Executor>();
sut.Object.ExecuteAction(new ActionRequest
{
ActionType = ActionType.Bar
});
}
I fiddled around with CallBase, but it didn't get me anywhere. Is there anyway I can solve this easily without dependency injection of these classes and adding interfaces? Is this possible just using Moq?
The only thing I can think to do currently is move the Execute methods into the Executor class and rename them to ExecuteFoo() and ExecuteBar(), but I have a lot of code to move so they'd have to be partial classes (sub classes?).
The problem is not with the mocking of the method but with the creation of the concrete class. The creation of Foo and Bar need to be inverted out of the Executor. It is responsible for executing the action, not creating it. with that this interface was created to handle the creation.
public interface IActionCollection : IDictionary<ActionType, Func<IExecute>> {
}
think of this as a collection of factories or a collection of creation strategies.
A common interface was created for the actions.
public interface IExecute {
bool Execute(ActionRequest request);
}
public class Foo : IExecute {
public virtual bool Execute(ActionRequest request) {
throw new NotImplementedException();
}
}
public class Bar : IExecute {
public virtual bool Execute(ActionRequest request) {
throw new NotImplementedException();
}
}
And the Executor was refactored to use dependency inversion.
public class Executor {
readonly IActionCollection factories;
public Executor(IActionCollection factories) {
this.factories = factories;
}
public bool ExecuteAction(ActionRequest request) {
if (factories.ContainsKey(request.ActionType)) {
var action = factories[request.ActionType]();
return action.Execute(request);
}
return false;
}
}
With that refactor done the Executor can be tested with fake actions.
public void GivenARequestToFooShouldExecuteFoo() {
//Arrange
var expected = true;
var key = ActionType.Foo;
var action = new Mock<Foo>();
action.Setup(x => x.Execute(It.IsAny<ActionRequest>())).Returns(expected);
var actions = new Mock<IActionCollection>();
actions.Setup(_ => _[key]).Returns(() => { return () => action.Object; });
actions.Setup(_ => _.ContainsKey(key)).Returns(true);
var sut = new Executor(actions.Object);
var request = new ActionRequest {
ActionType = ActionType.Foo
};
//Act
var actual = sut.ExecuteAction(request);
//Assert
Assert.AreEqual(expected, actual);
}
A production implementation of the factory collection can look like this
public class ActionCollection : Dictionary<ActionType, Func<IExecute>>, IActionCollection {
public ActionCollection()
: base() {
}
}
and configured accordingly with your concrete types.
var factories = ActionCollection();
factories[ActionType.Foo] = () => new Foo();
factories[ActionType.Bar] = () => new Bar();
I am using Rhino Mocks to stub out the functionality of a SOAP endpoint and for the most part it works. But, the interface is quite quirky and I am struggling to get the following to work (i have renamed the classes for simplicity)
public interface IWebService
{
void CopyFile(Request request);
}
public interface IService
{
void CopyFile(string filename, byte[] data);
}
public class Request
{
public string Filename { get; set; }
public byte[] Data { get; set; }
}
public class Service : IService
{
IWebService _service;
public Service(IWebService service)
{
_service = service;
}
public void CopyFile(string filename, byte[] data)
{
_service.CopyFile(new Request() {Filename = filename,Data = data });
}
}
Now, in my test I have something like this
[TestCase]
public void TestFileCopyFailsIfFilenameIsMissing()
{
IWebService serviceMock = MockRepository.GenerateMock<IWebService>();
serviceMock.Expect(x => x.CopyFile(Arg<Request>.Is.Equal(new Request() { Filename = Arg<string>.Is.Null, Data = Arg<byte[]>.Is.Anything }))).Throw(new Exception());
Service service = new Service(serviceMock);
service.CopyFile(null, new byte[] { });
}
Which throws the exception:
An exception of type 'System.InvalidOperationException' occurred in Rhino.Mocks.dll but was not handled in user code
Additional information: Use Arg ONLY within a mock method call while recording. 1 arguments expected, 3 have been defined.
I have tried the all possibilities in the world on this one, but cant get it right. If i dont use Arg and use
Expect(null, new byte[]{});
it will always pass no matter what
I suggest to use WhenCalled and in this method check Request object.
bool isCorrectParam = false;
IWebService serviceMock = MockRepository.GenerateMock<IWebService>();
serviceMock.Expect(x => x.CopyFile(null))
.IgnoreArguments()
.WhenCalled(x =>
{
Request req = x.Arguments[0] as Request;
if (req.Data.Count() == 0 && req.Filename == null)
{
isCorrectParam = true;
}
});
Service service = new Service(serviceMock);
service.CopyFile(null, new byte[] { });
Assert.IsTrue(isCorrectParam);
you can also use Matches...
serviceMock.Expect(x => x.CopyFile(Arg<Request>.Matches(r => r.FileName==null))).Throw(new Exception());
I'm using WCF and I made my own proxy in the client, and i want to create a method using lambda expression or Action that will excute everything.
Here is my proxy:
public class BooksProxy
{
public ChannelFactory<IBooksService> Channel { get; set; }
public BooksProxy()
{
Channel = new ChannelFactory<IBooksService>("endpoint");
}
public IBooksService CreateChannel()
{
return Channel.CreateChannel();
}
}
Here is how i use the proxy:
IBooksService proxy = BooksProxy.CreateChannel();
IList<string> lst = proxy.GetStrings();
((ICommunicationObject)proxy).Close();
I want to do something like this in the BooksProxy class:
public void Execute(Action<...> action)
{
IBooksService proxy = this.CreateChannel();
/* executing here. */
((ICummunicationObject)proxy).Close();
}
And to call it like this maybe:
IList<string> result = null;
BooksProxy.Execute(proxy => { result = proxy.GetStrings(); });
Not quite sure how to do that...
Ok, so I figured how to do it.
Here is the Proxy, The idea is to make it generic:
public class Proxy<T>
{
public ChannelFactory<T> Channel { get; set; }
public Proxy()
{
Channel = new ChannelFactory<T>("endpoint");
}
public T CreateChannel()
{
return Channel.CreateChannel();
}
}
Now here is the trick :
For void methods :
public void Execute(Action<T> action)
{
T proxy = CreateChannel();
action(proxy);
((ICommunicationObject)proxy).Close();
}
For return:
public TResult Execute<TResult>(Func<T, TResult> function)
{
T proxy = CreateChannel();
var result = function(proxy);
((ICommunicationObject)proxy).Close();
return result;
}
Where the TResult is the returning type.
How to use:
Proxy<IService> proxy = new Proxy();
// for a void method
Proxy.Execute(prxy => prxy.Method());
// for non void method.
var result = Proxy.Execute(prxy => prxy.Method());
So, to sum up, here is how the proxy class should look like:
public class Proxy<T>
{
public ChannelFactory<T> Channel { get; set; }
public Proxy()
{
Channel = new ChannelFactory<T>("endpoint");
}
public T CreateChannel()
{
return Channel.CreateChannel();
}
public void Execute(Action<T> action)
{
T proxy = CreateChannel();
action(proxy);
((ICommunicationObject)proxy).Close();
}
public TResult Execute<TResult>(Func<T, TResult> function)
{
T proxy = CreateChannel();
var result = function(proxy);
((ICommunicationObject)proxy).Close();
return result;
}
}
I recommend this solution for a custom wcf proxy without using any service reference, its really simple and easy.
This question was already asked here on SO but the answer refers to NHibernate 3.2.0.
So, is there a way to decompile the dynamic proxy classes that are generated by NHibernate 4.0?
using a custom Proxyfactory should do the trick. Example config using FluentNHibernate
var config = Fluently.Configure()
.ProxyFactoryFactory<MyProxyFactoryFactory>()
which uses the classes
class MyProxyFactoryFactory : DefaultProxyFactoryFactory, IProxyFactoryFactory
{
IProxyFactory IProxyFactoryFactory.BuildProxyFactory()
{
return new MyProxyFactory();
}
}
class MyProxyFactory : AbstractProxyFactory, IProxyAssemblyBuilder
{
const string PathToSave = "D:/";
private readonly ProxyFactory factory;
public MyProxyFactory()
{
factory = new ProxyFactory(this);
}
public override INHibernateProxy GetProxy(object id, ISessionImplementor session)
{
try
{
var initializer = new DefaultLazyInitializer(EntityName, PersistentClass, id, GetIdentifierMethod, SetIdentifierMethod, ComponentIdType, session);
object proxyInstance = IsClassProxy
? factory.CreateProxy(PersistentClass, initializer, Interfaces)
: factory.CreateProxy(Interfaces[0], initializer, Interfaces);
return (INHibernateProxy)proxyInstance;
}
catch (Exception ex)
{
throw new HibernateException("Creating a proxy instance failed", ex);
}
}
public override object GetFieldInterceptionProxy(object instanceToWrap)
{
var interceptor = new DefaultDynamicLazyFieldInterceptor();
return factory.CreateProxy(PersistentClass, interceptor, new[] { typeof(IFieldInterceptorAccessor) });
}
public AssemblyBuilder DefineDynamicAssembly(AppDomain appDomain, AssemblyName name)
{
return appDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave, PathToSave);
}
public ModuleBuilder DefineDynamicModule(AssemblyBuilder assemblyBuilder, string moduleName)
{
return assemblyBuilder.DefineDynamicModule(moduleName, moduleName + ".mod", true);
}
public void Save(AssemblyBuilder assemblyBuilder)
{
assemblyBuilder.Save("generatedAssembly.dll");
}
}
I am trying to mock a delegate, using Moq, but so far everything im doing is in vain.
I have made a small example of how the setup is:
1.A proxy class is abstracting a WCF service
public interface IServiceProxy
{
void FooService(ServiceProxy.FooServiceDelegate service);
}
public class ServiceProxy : IServiceProxy
{
private readonly EndpointAddress _fooServiceEndpoint;
public ServiceProxy(IConfiguration configuration)
{
_fooServiceEndpoint = new EndpointAddress(new Uri(configuration.WcfServiceEndpoint));
}
public delegate void FooServiceDelegate(IFooBar proxy);
public void FooService(FooServiceDelegate service)
{
Do<IFooBar>((service.Invoke), _fooServiceEndpoint);
}
private void Do<T>(UseServiceDelegate<T> f, EndpointAddress address)
{
UsingService<T>.Use(f.Invoke, address);
}
}
2.The service definition
/// <summary>
/// This is the interface the WCF service exposes
/// </summary>
public interface IFooBar
{
string Hello(string name);
}
3.And the class that uses the proxy
public class DoFoo
{
private readonly IServiceProxy _serviceProxy;
public DoFoo(IServiceProxy serviceProxy)
{
_serviceProxy = serviceProxy;
}
public string SayHello(string name)
{
var response = string.Empty;
_serviceProxy.FooService(proxy => { response = proxy.Hello(name); });
return response;
}
}
I would like to test that the methods defined on the delegate FooServiceDelegate with the input IFooBar is in fact called and also i would like to be able to mock the responce from a methodcall on a IFooBar via the delegate.
So far my attempts has been in vain, so i hope that there are some moq experts that can help here.
Here is an example of a test, that of course does not work as it is now.
[TestClass()]
public class DoFooTests
{
[TestMethod, TestCategory("Unit")]
public void SayHelloJohn_ShouldUseServiceProxy()
{//SETUP
var serviceMock = new Mock<IFooBar>(MockBehavior.Loose);
var delegateMock = new Mock<ServiceProxy.FooServiceDelegate>(MockBehavior.Strict);
var serviceProxyMock = new Mock<IServiceProxy>(MockBehavior.Strict);
serviceProxyMock.Setup(m => m.FooService(delegateMock.Object));
var name = "John";
var response = $"Hello {name}";
//Im trying something like this (of course this does not work...)
delegateMock.Setup(m => m.Hello(name)).Returns(response);
//EXECUTE
var doFoo = new DoFoo(serviceProxyMock.Object);
var result = doFoo.SayHello(name);
//ASSERT
// Do some assertions here....
}
}
You have to call the delegate when FooService is executed:
[TestMethod]
public void SayHelloJohn_ShouldUseServiceProxy()
{
const string EXPECTED_RESULT = "Hello John";
const string NAME = "John";
var fakeServiceProxy = new Mock<IServiceProxy>(MockBehavior.Strict);
var fakeFooBar = new Mock<IFooBar>(MockBehavior.Loose);
fakeFooBar.Setup(bar => bar.Hello(NAME)).Returns(EXPECTED_RESULT);
fakeServiceProxy.Setup(proxy => proxy.FooService(
It.IsAny<ServiceProxy.FooServiceDelegate>()))
.Callback<ServiceProxy.FooServiceDelegate>(arg => arg(fakeFooBar.Object));
var target = new DoFoo(fakeServiceProxy.Object);
var result = target.SayHello(NAME);
Assert.AreEqual(EXPECTED_RESULT, result);
}
The above snippet execute proxy => { response = proxy.Hello(name); }) when you call SayHello method.