First of all, I am also in the process of overcoming overthinking and confusion :)
Now, onto the real deal, you are over complicating your design. Let's take it from scratch and see where you want to go and what you have at your disposal to get there.
1. What you want
You want that, given a RegionRequest, you want something that will take that request and somehow persist it. At this moment, you don't care how it will do it, what sort of technology it will use, you just want it done. The interface (and part of the contract) is
public interface IRegionService
int AddRegion(RegionRequest regionRequest);
This is all the client classes that want to send a region request need to know about a region service. Anything more than this is a leaky abstraction!
2. What you have
You know for sure that you will be using a certain framework for storing that information - but you don't want any project or class needlessly knowing about it.
Some general theory
It is vital that you get assembly dependencies correctly!
I won't rant too much about this, but instead redirect you to a very concise and well-written explanation of architectural dependency management.
The idea is that you want to keep your Domain/Business project totally in the dark regarding what technologies (be them data or presentation) you will be using. The only projects that should have any knowledge about third party software or more low-level implementations should be the ones that adapt these tools to your domain's needs and the project where your composition root resides (so it can actually specify an implementation for an interface inside your domain).
Going back to your application's domain
Any client class that wishes to add a region (be it webapi,winform,console,mvc etc), should only depend on the interface above!
(As an aside, once you have decided this you can and should go ahead and create unit tests for those clients and check whether they will call this interface, that you will have mocked in unit tests).
For example, your WebApi controller might look like this:
public sealed class RegionController : ApiController
private readonly IRegionService regionService;
public RegionController(IRegionService regionService)
this.regionService = regionService;
public IHttpActionResult Post(int someId, string someName)
var request = new RegionRequest(someId, someName);
var result = this.regionService.AddRegion(request);
if (result == 0)
else if (result == -1)
With the above in mind let's take a look at how your project dependencies
Note that all dependencies point toward the business project. They all must conform to the interfaces it is dictating. It is the one telling the client (WebApi, WCF, etc.) what it can do and telling the data libraries (EF, WCF, etc.) what the data they should be supplying must look like.
Putting the third party data access to work
Now that we have defined the client and the business/service/domain layer, all that is left is to implement something that will actually persist that RegionRequest. In order to do that, we must adapt that third party library to our needs - more precisely, to the contract specified by your IRegionService, RegionRequest and the accompanying unit tests.
public class SomeThirdPartyRegionService : IRegionService
private SomeUnitOfWork someUnitOfWork;
public SomeThirdPartyRegionService(SomeUnitOfWork someUnitOfWork)
this.someUnitOfWork = someUnitOfWork;
public int AddRegion(RegionRequest regionRequest)
catch (SomeException e)
Based on the simple example you have given, this should be it!
Inside your business layer you'll have the RegionRequest and IRegionService and inside the ThirdPartyAdapter project you'll have that adapter class. Nothing more, since this service of yours seems to be doing simple CRUD operations.
But what if I need to add some more business logic, like validation? Where do I put that?
Suppose you have to do some validation on that request - ensure that the parameters inside at least adhere to a given format (for example an ISO code).
The place where this kind of logic, namely domain logic, resides is of course... the domain layer. Now, you have 2 choices: add this logic to the RegionRequest object (in the constructor or otherwise) or inside a new composite implementation of the IRegionService:
public class RegionService : IRegionService
private readonly IRegionService regionServiceImplementation;
public RegionService(IRegionService regionServiceImplementation)
this.regionServiceImplementation = regionServiceImplementation;
/// <inheritdoc />
public int AddRegion(RegionRequest regionRequest)
if (!Regex.IsMatch(regionRequest.SomeCode, "SomePattern"))
I won't go into the validation example inside the RegionRequest, since it is fairly trivial.
For the grand finale, this is what your high-level view of your solution should look like:
And the composition root (of a console app), the place where all the interfaces get to meet their implementations
public class Program
public static void Main()
var someUnitOfWork = new SomeUnitOfWork();
var someThirdPartyRegionService = new SomeThirdPartyRegionService(someUnitOfWork);
var service = new RegionService(someThirdPartyRegionService);
var controller = new RegionController(service);