HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Call to external web service

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
callserviceexternalweb

Problem

The architecture is showing a call to an external Web Service which is called by me. Then I will expose the data using WCF to be callable from another WCF client. But I really don't like how it's done. Interfaces, contracts, implementation in the BLO and implementations on the DAL.

7 time copy & paste of method which just call another identical method.

P.S: I've changed the name of the methods between the image and the code.. In the code I've called the main duplicate method GetExampleData / GetExampleDataInfo.

```
namespace .Risk.WCF.Services
{
public static class LeagueServerSingletonContainer
{
private static volatile IWindsorContainer serverInstance;
private static readonly object serverSyncRoot = new Object();

public static IWindsorContainer ServerContainer
{
get
{
if (serverInstance == null)
{
lock (serverSyncRoot)
{
if (serverInstance == null) // double-check
{
IWindsorContainer serverContainer = SingletonContainerFactory.ConfigureContainer(
"LeagueServerWindsor.config")
.Install(new LeagueWcfClientsWindsorInstaller());

serverInstance = serverContainer;
}
}
}
return serverInstance;
}
}
}
}

namespace .Example.WCF.Services
{
public class ExampleService : IWCFService, IExampleService
{
public ExampleApiResponse GetExampleData(int targetId, DateTime? dateFrom,
DateTime? dateTo)
{
var apiSessionKey = InitSessionKeyInformation();
return ExampleSingleton.Example()
.GetExampleDataInfo(apiSessionKey, targetId, dateFrom, dateTo);
}
}
}

namespace .Example.WCF.Services.Contract

Solution

You've turned your IoC container into a Service Locator (happens when you pass the IoC container around as a dependency)!

public void Install(IWindsorContainer container, IConfigurationStore store)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^ here!



Advantages



  • The "service locator" can act as a simple run-time linker. This allows code to be added at run-time without re-compiling the application, and in some cases without having to even restart it.



  • Applications can optimize themselves at run-time by selectively adding and removing items from the service locator. For example, an application can detect that it has a better library for reading JPG images available than the default one, and alter the registry accordingly.



  • Large sections of a library or application can be completely separated. The only link between them becomes the registry.




But this comes at a price:


Disadvantages



  • Things placed in the registry are effectively black boxes with regards to the rest of the system. This makes it harder to detect and recover from their errors, and may make the system as a whole less reliable.



  • The registry must be unique, which can make it a bottleneck for concurrent applications.



  • The registry can be a serious security vulnerability, because it allows outsiders to inject code right into an application.



  • The registry hides the class' dependencies, causing run-time errors instead of compile-time errors when dependencies are missing.



  • The registry makes the code more difficult to maintain (opposed to using Dependency injection), because it becomes unclear when you would be introducing a breaking change



  • The registry makes code harder to test, since all tests need to interact with the same global service locator class to set the fake dependencies of a class under test.




(http://en.wikipedia.org/wiki/Service_locator_pattern)

By doing this, you've introduced tight coupling between ExampleService and ExampleSingleton, which has become ambient context - which is a DI/IoC anti-pattern that you should strive to eliminate.

The solution is to inject the dependencies through the class' constructor, ideally as an interface (/abstraction - an abstract class works just as well).

Your architecture relies heavily on static classes and the Singleton [anti-]pattern, which is making your solution essentially untestable, as far as I can tell.

Code Snippets

public void Install(IWindsorContainer container, IConfigurationStore store)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^ here!

Context

StackExchange Code Review Q#42663, answer score: 6

Revisions (0)

No revisions yet.