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.
Related
I'm currently developing a web API in .NET core. I have three projects in my solution with the following references:
Web -> Services -> DataAccess
So the web layer does not have a direct reference to the DataAccess layer.
My question is: What is the right way to get the connectionstring in this type of architecture with three layers? I have read around, but can't find any nice solution where I can access my connectionstring in the third layer, just because the web layer does not have a reference to the third layer.
I came accross this approach:
services.Configure<ConnectionConfig>(Configuration.GetSection("ConnectionStrings"));
services.AddScoped<IQueryHelper>(c => new QueryHelper(cn));
This work well if I just have two layers, where the QueryHelper is in the service-layer.
But I want to access one or multiple connectionstrings in my DataAccess-layer.
Edit: Injecting the configuration might not be the smartest idea as you can read here. Better way would be to configure options for each connection string that can be accessed by the DAL aswell.
services.Configure<MyConnectionInfo>(options => Configuration.GetSection("MyConnectionInfo").Bind(options));
Now in your repository just inject IOptions<MyConnection> and use the values.
Old Answer: Just inject your configuration into your datalayer-classes. Before you have to register the configuration with the ioc-container.
services.AddSingleton(typeof(IConfiguration), Configuration);
Now access the connectionstrings you need by injection the instance of IConfiguration. You could also configure more options instead, but injecting the configuration is fine aswell.
I created a Data Access Layer project in my solution that uses Entity Framework/Web API. Happy with my results after some testing I decided I wanted another service for Business Logic.
Being that I'll have several applications interfacing with the business logic layer I assumed creating another restful service with Web API would be the best approach. With that said, I'm scratching my after learning everything regarding models and entity framework. Being that the DAL is interfacing with the database I'm assuming I won't be using models at all in this new project and just building a controller that call my DAL service. Is this correct or is there something I'm missing entirely here?
And if I'm not missing anything can someone point me in the right direction on how to call a restful service from a restful service?
Web Api can add value to an MVC application if you want to post or fetch data server-side without a postback.
As for services, it's common to put business logic in the controller and have the controller call an internal library that acts as the DAL.
Example...
MyProject.soln
MyProject.Library (this is your DAL)
MyProject.Services (Web API)
MyProject.Web (MVC site)
I like a MVVM/Repository/Mapper pattern. It's extra work up front but very extensible and pretty SOLID. It typically includes:
Data models that represent objects in the database
Repositories for each (or most) models that do ONLY CRUD operations. No transformations.
View Models that represent the data I need in views or service controllers
Mapper classes that transform my data models to View Models.
Controller example
public IHttpActionResult Post(MyViewModel viewModel)
{
if (!ModelState.IsValid)
{
return Content(HttpStatusCode.BadRequest, ModelState);
}
var modelMapper = new ModelMapper();
var model = modelMapper.getModelFromViewModel(viewModel);
var modelRepository = new ModelRepository();
modelRepository.Save(model);
return Ok();
}
I have around 6 WCF services that I want to host in an MVC application, routing requests to /services/foo to WcfFooService and /services/bar to WcfBarService
I can accomplish IoC with StructureMap within the services and inject my constructor dependencies by using the example that Jimmy Bogard blogged about here:
Jimmy's article is great, but I'm trying to extend it to work with multiple services hosted within the same MVC application. Essentially, the part at the bottom is the part that is causing me a few headaches:
public class StructureMapServiceHostFactory : ServiceHostFactory
{
public StructureMapServiceHostFactory()
{
ObjectFactory.Initialize(x => x.AddRegistry<FooRegistry>());
//var iTriedThisToo = ObjectFactory.Container;
//container.Configure(x => x.[etc]);
}
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new StructureMapServiceHost(serviceType, baseAddresses);
}
}
With a single WCF service - routing MVC requests to a specific url via the StructureMapServiceHostFactory shown above works brilliantly - but - If (for example) I create a StructureMapServiceHostFactory2 for the /services/bar call, to allow for a different Registry to be used, when the MVC app spins up, it appears to call each factory in turn as it runs through RouteConfig.cs and adds the routes, so ultimately I don't get configured instances that the first ServiceHostFactory should provide.
It doesn't make a difference if I call Initialize(); or attempt to grab the Container property and call Configure on it, either.
Am I on a hiding to nothing with this? The major reason for requiring registry isolation is due to different NHibernate configuration, but I could configure Named instances of SessionFactory and Session for NHibernate purposes and then use a single registry to get around this. In my mind I wanted the WCF service and MVC-hosting to be capable of using their own IoC containers in isolation, which is why I went down this route.
Is there any way that I can accomplish this?
Ok, so it would appear the only person capable of answering this was me, by virtue of a re-think and 're-architecting' the solution so that the problem doesn't exist in the first place.
I now have a capable way of hosting these services and maintaining IoC with StructureMap neatly per service, without any conflicting concerns.
If you find yourself in a similar position with SOA taking over (SOATO?) - taking a step back is a good start ;)
I currently have something like this for my route table. Is there a nicer way to handle versioning in WCF Web API or conventional WCF?
RouteTable.Routes.MapServiceRoute<Service1>("1.0/Route1", Config1);
RouteTable.Routes.MapServiceRoute<Service2>("1.0/Route2", Config2);
RouteTable.Routes.MapServiceRoute<Service3>("1.0/Route3", Config3);
RouteTable.Routes.MapServiceRoute<Service4>("1.0/Route4", Config4);
You could do that, but it is very protocol-bound, in this case HTTP. I wonder if there is a way to do that without worrying so much about protocols? Ideally we only want to do it once and not for each transport out there. Luckily there is a way, let me explain.
At the end of the day, your WCF internals should be protocol agnostic. By that I mean by the time a method is invoked on your service, we should not care whether it came by REST, TCP, HTTP or named pipes.
In WCF this is pretty easy and so is versioning. With versioning we can learn much about .NET interface versioning particularly when it has nothing to do with WCF. The idea is that your service should realize:
interface ISomething1 { ... }
Later when a new method or changes are required you should:
interface ISomething2 : ISomething1 { void SomethingNew (...) }
It's then a simple matter to publish your service with 2 endpoints in config, one pointing to ISomething1 and the other to ISomething2.
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.