pass Business Layer to WCF service - c#

I have a WCF service and i am trying to write unit test cases for that. I am calling Business Layer and some other WCF service from one of the methods in that service. I am already using IcO pattern for my Business Layer. but in order to use Mock object of my Business Layer and WCF service here, i need to pass it at the time of creating that service instance. If i change my default constructor to accept it as a parameter, i will have to expose them to the service consumers.
if i change the constructor of the service, it will look like this:
public MyService(MyBusinessLayer bl, SomeWCFService otherSrvc)
{
}
Is it OK to do so? Am i doing something wrong here?

Send an interface of the service instead of an impementation. That way you can swap out the implementation at runtime with your mock.

Related

How we can perform integration test on service fabric (stateless service)?

I'ld like to perform integration on stateless service in service fabric.Please help me on this. I have created the stateless service like c# web api.
In order to perform integration tests on your Reliable Service there is a number of dependencies you need to mock and take care of. You will not be able to test all situations or behavior of your service this way, the way the FabricRuntime hosts and runs services is difficult to replicate (without writing your own FabricRuntime equivalency). It is also worth noting that there is no way to run FabricRuntime without a cluster (including local development cluster).
You also need to consider how advanced your integration tests should be. For instance, does your service call out to other service (including actors) within the same cluster using fabric transport (the default communication model) that you want to include in your integration test? Do you need to ensure that state is persisted across multiple activations of the same service partition?
First you need to get rid of all hard dependencies to FabricRuntime (to things with dependencies to it) and also static support classes in your code:
Service/Actor proxy
Don't use the static ServiceProxy.Create<..)(..)> when calling other services, instead make sure your Service accepts an instance of IServiceProxyFactory in the constructor and use that instance to create proxies to services your service calls. Same goes for ActorProxy.Create<..>(..), replace this with an instance of IActorProxyFactory. In your program.cs where the service is constructed, give the service new ServiceProxyFactory() and new ActorProxyFactory(). That's the easy part, now you need to mock those so that your integration tests can actually create some form of proxy for downstream services. You will also need to create some form of container (like a mock FabricRuntime) that holds instances of called services and actors. It also gets tricky if you wan't to test that the RunAsync method of your service performs some function. Beware of creating this static though if you want to run it in a test runner,
you don't want different tests to get mixed up in the same container.
Service context
You need to mock your StatefulServiceContext well and how your Service is created. Your Service constructors need to accept an instance of StatefulServiceContext to pass along to the base class, so you are free to supply your own mocked instances of context there when you create the service.
public StatefulService(StatefulServiceContext serviceContext)
: base(serviceContext) {}
Service settings and activation context
You also need to see if your service implementation tries to read ICodePackageActivationContext or any of the settings from the Service manifest (like shown in this SO answer Where do you set and access run-time configuration parameters per environment for service fabric?). In that case you need to replace it with your own mockable version and you need to inject that in the constructor as well. What you find in most samples is a call to the service context, like this:
this.Context.CodePackageActivationContext.GetConfigurationPackageObject("Config");
If you do it this way in your service then you need make sure you have a mock of StatefulServiceContext as well and how your Service is created. When you register your service with the runtime in Program.Main() then you get and instance of StatefulServiceContext in the register call:
ServiceRuntime.RegisterServiceAsync("ServiceType",
context => new Service(context)).GetAwaiter().GetResult();
State
In order to mock state and get it to behave similar to what it will when running in a real cluster you need to mock the underlying handler for reliable state: IReliableStateManagerReplica and you need to add an overloaded constructor to your services that accepts an instance of that and sends it to the base:
public StatefulService(StatefulServiceContext serviceContext, IReliableStateManagerReplica reliableStateManagerReplica)
: base(serviceContext, reliableStateManagerReplica) {}
For actors its IActorStateProvider you need to mock if you want to handle state in your integration tests.
Summary
Depending on how advanced you want your integration tests to be and how close to the real execution model you want it to be, you may end up having to mock and replace a large number of classes/interfaces. The Web reference application sample
https://github.com/Azure-Samples/service-fabric-dotnet-web-reference-app has some implementation of Mocks for required classes, also https://github.com/loekd/ServiceFabric.Mocks contains Mocks for testing, although you might need to alter the code if you really want to run integration tests and not just unit tests.
There is no difference on your integration tests on stateless web api with a regular api.

How to use SOAP service generated class methods?

I have created a SOAP service.
Now i want to consume it in a c# client application. I added the service using 'Add service reference' and service reference is added to client.
All my service entities are in service. And in current scenerio i can't move them to a common library.
Problem is, my service endpoint is accepting List<Foo> as parameter.
Foo has a method Boo.
In client, when i try to Foo.Boo() i get Cannot resolve symbol Boo error.
Unfortunately only methods on the service itself are exposed via a SOAP web service, methods on objects used as parameters or return values are not. If the method relates to a server-side operation then you could expose it at the service root level taking the instance object as parameter, or if it relates to a client-side operation you could consider adding it as a client-side extension method.

Service references to my wcf services issue with client objects, don't have open/close in interface?

Trying to unit test my asp.net mvc 2 controllers, and having an issue mocking my wcf client code.
My interfaces for the wcf services dont' have open/close so I can do this:
IMyServiceClient client = new MyServiceClient();
And as a result it is harder to mock (moq) this class.
How can I work around this?
The reason IMyServiceClient doesn't have Open & Close methods is that MyServiceClient inherits from the System.ServiceModel.ClientBase<T> class. ClientBase<T> implements the ICommunicationObject interface which provides those methods. Mock this class by configuring it for mocking multiple interfaces (IMyServiceClient and ICommunicationObject).

Init properties in my base wcf service

I have set up some WCF services that I use to call from javascript to enable ajax calls such as retrieving data in JSON format.
All my services are configured in a web.config etc and I code in c#.
All my services inherit from a BaseService object which has some common properties that are share between all services, for example a logger object, configuration object etc.
My question is, how/where I can set up/assign values to these properties? ie. set up the base service logger property with an instant of a custom logger I created. Apologies if my question is vague but any help would be great.
Properties for Service implementation object cannot be set from client (any kind) because only contract is visible to client. Further, properties such as config and logger are anyway not meant to be part of contract but rather service implementation - so they must get set at server side automatically(i.e. by application infrastructure) for each service object. You have a couple of choices:
Use constructor (either that of BaseService or actual service class) to initialize these properties.
Use IoC/DependencyInjection container (for example, Unity, StructureMap)

What is the difference between a DDD service and a WCF service?

I have a DDD class library. In it, I have the following structure:
> Core
> - DataAccess ( my LINQ repositories)
> - Domain ( my data objects)
> - Impl (my services)
I have recently added a WCF project to my solution. This project will
be exposing JSON web methods to an iPhone client. The WCF methods are
not too sophisticated - GetCustomers / GetCustomerDetails / GetAlerts
GetAlertDetails / GetProblems / GetProblemDetails / GetInventory /
GetInventoryDetails, GetDataPoints / GetDataPointDetails / etc...
What I am noticing is that most of the methods in WCF are exposed
by my services layer in my DDD model. So, I am finding myself doing
a lot of code like this:
public List<Alert> GetAlerts()
{
AlertSerice _as = new AlertService;
List<Alert> alerts = _as.GetAlerts();
return alerts;
}
This doesn't feel right to me. I am wondering if I should be doing away with my Impl folder (with all
the DDD services) and recompile. Then, add the DLL as a refcerence in my WCF project and code my
previous DDD services as WCF methods?
Does WCF really just need the Domain and DataAccess layers?
Thanks in advance.
AlertSerice _as = new AlertService;
List<Alert> alerts = _as.GetAlerts();
It seems possible you may be using Domain Services incorrectly.
In DDD, Domain Services are used when multiple aggregate roots must be involved in an operation.
GetAlerts would appear to be functionality that clearly belongs in an AlertRepository (and not just belongs, but is the core functionality of that Repository).
As for WCF Services, they are a public endpoint. Their job is to receive requests from a client and carry out commands on the domain or queries. The focus in this sort of service is usually translation - from primitive typed input parameters to DTO's for output.
From an architectural perspective using a distinct service layer to expose your data allows a level of abstraction, and isolation for protected and internal methods, you can simply plug in a different service handler (Service configuration) to expose the data in a binary or XML format. Where you need to spend your time is ensuring the levels of abstraction are clearly defined and ensure code access rules and security between layers exposed to the service layer are implemented.

Categories

Resources