I have a WCF service running with ASP.NET compatibility.
This service is supposed to be readonly and is created using web script factory.
I want to get the singleton instance from anywhere in code (different pages.. etc), and if it's not created it should be created, but if accessed directly for first time it shouldn't create another singleton instance if there was one already created from somewhere in code. Basically, I want a classic singleton, but not using static and the creation of the service should be the factory's job.
You can do this using an attribute on your wcf service:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class MySingleton : ...
{...}
With this your WCF service has a single instance, that is used by all callers.
For details see: http://msdn.microsoft.com/en-us/magazine/cc163590.aspx
Related
I am trying to implement an Employee Management System using DDD approach. The system is built using .Net Core. I have several Projects created for this system (UI, Application, Domain, Infrastructure). Now inside my Domain Layer, I have an Employee entity (that's the Aggregate root of Employee aggregate). The business requirement is that whenever an Employee is created, I need to do a Credit Check, and based on the result I am supposed to update a property called "IsCreditCheckDone" for the Employee entity. The Credit Check service is basically an external Rest Service. I am thinking to create an Interface called ICreditCheckService inside Domain.Services.Interfaces folder. I am thinking to do the implementation of ICreditCheckService in the Infrastructure layer inside the service folder. Also, ICreditCheckService will be injected into the Employee class and the Dependency will be mapped inside the Startup class of the UI project.
My question is, is it the correct approach to handle the Domain Service when it consumes the external systems? Or should it be done differently?
EMS.Domain
Entities
Employee.cs
Services
Interfaces
ICreditCheckService.cs (This will be injected to Employee entity)
EMS.Infrastructure
Services
CreditCheckService.cs (this service will make an http call to external Rest API)
In general, I think your design is good.
Two points, however:
Terminologically, The service that invokes an external api is not considered to be a domain service (a domain service runs logic that involves several entities). It is more like a repository.
Repository services should be injected not into entities but into application (use-case) services. For example, an application service invokes your credit-check service, then creates an employee entity passing to its ctor the boolean result.
My application is using SQL Server 2012, EF6, MVC and Web API.
It's also using a repository and assorted files such as:
DatabaseFactory.cs
Disposable.cs
IDatabaseFactory.cs
IRepository.cs
IUnitOfWork.cs
RepositoryBase.cs
UnitOfWork.cs
We already use a service layer between our controllers and the repository
for some complicated business logic. We have no plans EVER to change to a different database and it has been pointed
out to me that the recent thinking is that EF6 is a repository so why build
another repository on top of it and why have all of the files I have above.
I am starting to think this is a sensible approach.
Does anyone know of any examples out there that implement EF6 without a
repository, with a service layer. My search on the web has revealed many
complex code examples that seem over complicated for no reason at all.
My problem is also when using a Service Layer then where do I put:
context = new EFDbContext()
In the controller, the service layer or both ? I read that I can do this with dependancy injection. I already use Unity as an IOC but I don't know how I can do this.
Entity Framework IS already a Unit of Work pattern implementation as well as a generic repository implementation (DbContext is the UoW and DbSet is the Generic Repository). And I agree that it's way overkill in most apps to engineer another UoW or Generic Repository on top of them (besides, GenericRepsitory is considered to be an anti-pattern by some).
A Service layer can act as a concrete repository, which has a lot of benefits of encapsulating data logic that is specific to your business needs. If using this, then there is little need to build a repository on top of it (unless you want to be able to change your backend service technology, say from WCF to WebApi or whatever..)
I would put all your data access in your service layer. Don't do data access in your controller. That's leaking your data layer into your UI layer, and that's just poor design. It violates many of the core SOLID concepts.
But you do NOT need an additional UnitOfWork, or other layers beyond that in most cases, unless your apps are very complex and intended to work in multiple environments...
Setting up Unity for ASP.NET MVC and WebAPI is quite easy if you install and add the Unity.Mvc* and Unity.WebAPI* Nuget packages to your project. (The * is a version number, like 3 or 4 or 5. Look for the appropriate versions for your project. Here are for example the links to the Unity.Mvc 5 package and to the Untity.WebAPI 5 package.)
The usage of these packages is explained in this blog post.
The building blocks are roughly like so:
You build a unity container and register all your dependencies there, especially the EF context:
private static IUnityContainer BuildContainer()
{
var container = new UnityContainer();
container.RegisterType<MyContext>(new HierarchicalLifetimeManager());
container.RegisterType<IOrderService, OrderService>();
container.RegisterType<ICustomerService, CustomerService>();
container.RegisterType<IEmailMessenger, EmailMessenger>();
// etc., etc.
return container;
}
MyContext is your derived DbContext class. Registering the context with the HierarchicalLifetimeManager is very important because it will ensure that a new context per web request will be instantiated and disposed by the container at the end of each request.
If you don't have interfaces for your services but just concrete classes you can remove the lines above that register the interfaces. If a service needs to be injected into a controller Unity will just create an instance of your concrete service class.
Once you have built the container you can register it as dependency resolver for MVC and WebAPI in Application_Start in global.asax:
protected void Application_Start()
{
var container = ...BuildContainer();
// MVC
DependencyResolver.SetResolver(
new Unity.MvcX.UnityDependencyResolver(container));
// WebAPI
GlobalConfiguration.Configuration.DependencyResolver =
new Unity.WebApiX.UnityDependencyResolver(container);
}
Once the DependencyResolvers are set the framework is able to instantiate controllers that take parameters in their constructor if the parameters can be resolved with the registered types. For example, you can create a CustomerController now that gets a CustomerService and an EmailMessenger injected:
public class CustomerController : Controller
{
private readonly ICustomerService _customerService;
private readonly IEmailMessenger _emailMessenger;
public CustomerController(
ICustomerService customerService,
IEmailMessenger emailMessenger)
{
_customerService = customerService;
_emailMessenger = emailMessenger;
}
// now you can interact with _customerService and _emailMessenger
// in your controller actions
}
The same applies to derived ApiControllers for WebAPI.
The services can take a dependency on the context instance to interact with Entity Framework, like so:
public class CustomerService // : ICustomerService
{
private readonly MyContext _myContext;
public CustomerService(MyContext myContext)
{
_myContext = myContext;
}
// now you can interact with _myContext in your service methods
}
When the MVC/WebAPI framework instantiates a controller it will inject the registered service instances and resolve their own dependencies as well, i.e. inject the registered context into the service constructor. All services you will inject into the controllers will receive the same context instance during a single request.
With this setup you usually don't need a context = new MyContext() nor a context.Dispose() as the IOC container will manage the context lifetime.
If you aren't using a repository then I assume you would have some place to write your logic/processing that your service operation would use. I would create a new instance of the Context in that logic/process class method and use its methods directly. Finally, dispose it off right after its use probably under a "using".
The processing method would eventually transform the returned/processed data into a data/message contract which the service returns to the controller.
Keep the data logic completely separate from Controller. Also keep the view model separate from data contract.
If you move ahead with this architecture, you are going to be tightly coupling the Entity Framework with either your service or your controller. The repository abstraction gives you a couple things:
1) You are able to easily swap out data access technologies in the future
2) You are able to mock out your data store, allowing you to easily unit test your data access code
You are wondering where to put your EF context. One of the benefits of using the Entity Framework is that all operations on it are enrolled into a transaction. You need to ensure that any data access code uses the same context to enjoy this benefit.
The design pattern that solves that problem is the Unit of Work pattern, which by the looks of things, you are already using. I strongly recommend continuing to use it. Otherwise, you will need to initialize your context in your controller, pass it to your service, which will need to pass it to any other service it interacts with.
Looking at the objects you have listed, it appears to be a considerate attempt to build this app with enterprise architectural best practices. While abstractions do introduce complexity, there is no doubting the benefit they provide.
I have a simple app where I use global.asax to map a serviceroute to a wcf service through a custom servicehostfactory in Application_Start. The constructor of that service does some initial processing to set up the service which takes a bit of time.
I need this constructor to fire when its serviceroute is added automatically. I tried creating a clientchannel from global.asax and making a dummy call to spin up the service, but discovered the service isn't up yet -- it seems application_start has to return?
So how do I get the constructor of the service to fire when first mapped through global.asax without having to manually hit the service? Unfortunately AppFabric isn't an option for us, so I can't just use it's built-in autostart..
UPDATE
I was asked for a bit more detail;
This is like a routing management service. So I have Service1 -- it gets added as a serviceroute in global.asax. Now I have http://localhost/Service1
Inside Service1 I have a method called 'addServiceRoute'. When called, it also registers a route for Service2. Now I have http://localhost/Service1/Service2.
My initial solution from global.asax was to build a channelfactory to http://localhost/service1 but that wouldn't work. Service1 wasn't up yet and wouldn't come up till Application_Start returned (Still not sure why?). So then I thought I'd cheat and move that initial addserviceroute call to the constructor of service1. Also didn't work.
It was mentioned that this shouldnt be in the constructor -- i agree, this is just testing code.
A singleton was also mentioned, which might be ok, but I intend to have more than one instance of Service1 on a machine (in the same app pool) so I don't think that'll work?
** UPDATE #2 **
I was asked for sample code.. here it is from global.asax (trimmed a bit for brevity).. So http://localhost/Test DOES come up.. But if I have to use appfabric to warm up Test and get its constructor to fire, then don't I need Test.svc or something? How do I get appfabric to even see this service exists?
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Ignore("{resource}.axd/{*pathInfo}");
RouteTable.Routes.Add(
new ServiceRoute("Test", new MyServiceHostFactory(ITestService, BindingType.BasicHttpBinding, true), TestService));
}
What you describe requires singleton service (something you should avoid) because normally each call or session gets a new instance = a new call to constructor. In self hosted WCF service you can instantiate singleton service instance and pass it to ServiceHost constructor. In case of IIS hosted service used together with ServiceRoute you can try to create your own class derived from ServiceHostFactory and pass created service instance as a parameter to its constructor. In this factory class implement CreateServiceHost method and pass that existing service instance into ServiceHost constructor. To make this work your service class must still be handled as singleton through service behavior.
Btw. constructor should not do any time consuming operation. Constructor is for constructing object not for initializing infrastructure. Using constructor for such initialization is bad practice in the first place.
AppFabric autostart is what I would recommend - even though you say you cannot use it - this is the problem it was meant to solve (warming up your service).
As an alternative before AppFabric existed, you would have to use a scheduled task (a.k.a cron job) with an executable that calls into the service you want initialized. The way AppFabric autostart works is by using named pipes (net.pipe) to trigger the warm up - but it just does this exact thing when the service is recycled. The difference between the scheduled task approach and the AppFabric autostart is that the scheduled task doesn't know when your application pool has been recycled - you would need to poll your service periodically to keep it warm.
Alternatively you could consider hosting your WCF application outside of IIS via self-hosting. This would avoid the warm-up issue, but you wouldn't achieve many of the benefits of the IIS hosted container. See HttpSelfHostServer in the new MVC Web API or review using a standard ServiceHost.
Whats the best way to implement this.
I am building application that will be hosted as a web service. This app takes an employeeID and returns an employee object that contains lots of info regarding the employee. (name, status, full-time/part-time, etc)
I want the two existing apps we have (and more to come) to be able to call a method that the web service will have and return the employee object. (also at time this web service that returns the object may have new fields added to it - Pay rate, etc)
How would I go about creating a new object from this web service reference in the existing applications.
Would I decalre it like Dim Employee as new emp_webservice.employee ?
And then be able to use this object within the app? Or would the better practice be to also included the same class files? It seems like this would not be the way to go, since if I make a change to that class I then have to make it in all places
Thanks for any clarification on this.
When you add a reference to a web service in a .net application, the objects exposed by that web service exist in the namespace that you created for that web service when it was added to your application.
So, any reference to classes from that web service would need to reference the namespace for that web service, as you have indicated. You could also have an Imports WebServiceNameSpace if you don't want to fully qualify every class.
You can't really include the class files if you are using the automatic web service interface generation functionality that VS.Net provides.
Also, if you change properties in the web service, those updated properties won't be propagated to the client until you update the web service reference in your project.
Finally, if you want to add methods or additional properties to the web service classes on the client side, you can use Partial classes.
For example, let's say that the web service only provides an hourly pay rate, but I want to show a weekly salary in the client. I can extend the web service class as follows:
Namespace emp_webservice
Partial Public Class employee
Public Function GetWeeklyPayRate() As Decimal
Return Me.HourlyRate * 8 * 5
End Function
End Class
End Namespace
If we have a singleton class like LoadBalancer and need one instance per ASP.NET application, then where to store it ?
Currently I use Application.Add("LoadBalancer", LoadBalancer.Instance) in Application_Start() in Global.asax.
Also Application object is created by ASP.NET and there are multiple instances per application based on workload. Also I can declare a static instance of my LoadBalancer in Global.asax.
Which is preferred ? Any better idea ?
If it is a Singleton why do you want to store in Application items? Isn't it supposed to return the same instance when you use LoadBalancer.Instance from anywhere in the application?
In case your site is using load balancing or is ina web farm each server would have its instance of Application object and LoadBalancer.Instance.
You dont have to store a singleton object in Application object. Standard implementation of Singleton object holds good. http://msdn.microsoft.com/en-us/library/ff650316.aspx
But if you using a Web Farm its a different story, you should have the Singleton object hosted seperately on a different service and all the servers should request the object from that service using Remoting or WCF.
Use an IOC container like Castle Windsor. The default lifestyle in Castle Windsor is singleton.
http://www.castleproject.org/container/documentation/v21/usersguide/lifestyles.html