I have an IIS-hosted WCF application. Right now the service has this constructor:
public ClassService()
: this(new ClassRepository())
{
}
public ClassService(IClassRepository repository)
{
_Repository = repository;
}
The parameterless constructor is because WCF requires you to have a parameterless constructor when generating service proxies. Now, when I have the service proxy in the UI assembly, the constructor with the IClassRepository is not present so I can't inject an implementation of the repository.
How is this commonly done? One idea I have is that injection would take place not in the UI but in the Service but I am not sure if this would have some repercussions or just plain bad. Can someone give me some ideas?
What you need to do is implement a WCF InstanceProvider, delegating creation requests to your container of choice. Once you have your instance provider coded, you can install it in a ServiceHost by implementing a WCF service behavior. The service behavior, in turn, is installed by adding it to the collection ServiceHostBase.Description.Behaviors.
Here's an MSDN Magazine article on WCF extensibility.
Related
I need to create a service class for my constructor in which I need to load a lot of configurations from my appsettings.json.
I want this service to be created as singleton and need to load configurations values in the service itself. So please anyone suggest me the best way to do so. I am creating asp.net core webapi and using its core DI built in container.
The configuration is already pre-registered by the host that is used with ASP.NET Core. So you can just register your service as you would any other singleton service, and have it depend on the configuration by requiring IConfiguration in the constructor:
public class MyService
{
private readonly IConfiguration _config;
public MyService(IConfiguration config)
{
_config = config;
}
}
You can then register this service as a singleton directly in your ConfigureService method:
services.AddSingleton<MyService>();
Things that now depend on your service, for example constructors, will automatically get a reference to that service instance. And since it is registered as singleton, it will only be created once by the DI container.
If you want a bit more control over your configuration, then I would suggest you to adapt the options pattern to make sure that you can work with strongly typed configuration and to avoid unrelated configuration value from spilling into services that shouldn’t not have access to them.
I am usually working with WCF services that uses single instance context mode. Also service contract and behavior is in a WCF service Library.
If the service is hosted as a Windows Service or a Web service, they get their own projects that references the WCF service library. I like to keep this WCF service library running (for simply debugging with WCF Test Client) but it requires too much effort when I try to resolve dependencies through the behavior class.
Using Castle Windsor, I also have to make additional configuration for Castle Windsor WCF Integration Facility. I am just trying to resolve the object graph on service startup and I feel like it shouldn't be this hard.
I thought, since behavior instance is created only once I should be able to use it as the composition root. I can provide all dependencies using a single object and resolve it from the container like this:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class SampleService : ISampleService, IDisposable
{
private readonly IServiceManager _serviceManager;
private readonly IWindsorContainer _container;
public SampleService()
{
_container = new WindsorContainer();
_container.Install(new ServiceInstaller());
_serviceManager = _container.Resolve<IServiceManager>();
}
public string GetMessage()
{
return _serviceManager.GetMessage();
}
public void Dispose()
{
_container.Dispose();
}
}
I know it's a bad idea to explicitly ask the container to resolve a dependency but this saves me from so much trouble. I get to keep the default WCF configuration, I can run the WCF service library for debugging since I have a default constructor now. I also don't have to use Castle Windsor WCF integration Facility which was missing documentation last time I checked.
I guess Castle Windsor WCF integration Facility offers more features but I just want to resolve the dependencies. Is this approach likely to cause some problems? I haven't seen anyone do it like this so I would like to know if this would be legitimate use.
A little background info -
I'm trying to host a RESTful WCF service on Azure. As I understand, unless I have the ASP.NET type hosting on the role, I don't really need the global.asax class (which has the application_start method).
From basic prototyping, all I needed was the svc file and the implementation behind it and it automatically gets initialized on role startup (I mean, hosted up on IIS).This is great because I need no extra code other than web.config and my service is up and running. I don't need to create a new service host and start listening on it, etc. I'm able to deploy the role and POST messages to my service.
The problem -
I have custom logging and initialization classes implemented that I need to initialize when my service starts up. I configured my service to be a singleton and I'm not sure where I should put my custom initialization components.
Without an explicit application start method and my service configured as a singleton, can I assume that when the first request comes in, my service constructor gets called? (along with all my custom initialization?).
can I assume that when the first request comes in, my service constructor gets called?
Yes, but you should ask yourself whether you really want your service to run as a singleton. If you're happy with this then it will work fine; if you don't want it to run as a singleton then you should look into Russell's answer using a custom factory.
Look at Should WCF service typically be singleton or not? for some discussion about whether WCF services should be singletons. You need to decide for your situation, but generally WCF services are not singletons unless they need to be.
To implement a custom factory, see this MSDN link Extending Hosting Using ServiceHostFactory. As the link describes, extend the service host factory like so
public class DerivedFactory : ServiceHostFactory
{
public override ServiceHost CreateServiceHost( Type t, Uri[] baseAddresses )
{
return new ServiceHost(t, baseAddresses )
}
}
And then specify your factory in the ServiceHost directive
<% # ServiceHost
Service="MyNamespace.MyService"
Factory="MyNamespace.DerivedFactory" %>
You're looking for ServiceHostFactory. You can add a part to the SVC file to use a factory, where you can do any logging etc. you may need.
I have used this in the past to start a background worker to launch a separate thread for some background work.
http://msdn.microsoft.com/en-us/library/system.servicemodel.activation.servicehostfactory.aspx
Hope this helps you get where you need to be. :)
Where is the best place to put code for when a WCF service is just started up? Similar to Page_Load in a web application.
The service implementation constructor would be the obvious place but it also depends on your hosting model
1) run once code: IIS hosting = global.asax; self-hosting = Main / OnStart
2) run once per service instance: constructor of service class
3) Something more exotic: implement IInstanceProvider
In the class constructor of the service implementation.
Honestly the best place is the constructor and/or static constructor for your service class (for static members). There is no other WCF specific lifecycle event that will notify your service implementation when it's being created by the service host.
Now, if you're talking about the creation of services generically, that would mean you're willing to hook into the WCF runtime and there you can do things like get in the middle of the instance creation with a custom IInstanceProvider implementation.
I have a WCF service which implemented using Repository and UnitofWork patterns.
And now I am getting following error:
The service type provided could not be loaded as a service because it does not have a default (parameter-less) constructor. To fix the problem, add a default constructor to the type, or pass an instance of the type to the host.
When I worked WIHTOUT these patterns it did not throw any error.
HELP ?? SUGGESTIONS? How to get passed this error?
Following is the code snippet:
public class Service : IService
{
private IUnitOfWork _unitOfWork;
private IMyRepository _myRepository;
// Dependency Injection enabled constructors
public Service(IUnitOfWork uow, IMyRepository myRepository)
{
_unitOfWork = uow;
_myRepository = myRepository;
}
}
If you use default service instancing you must provide parameterless constructor. Your design provides dependency injection through constructor. In such case you must have your own instance provider to call the constructor and create service instance. You can create per service instance provider, behavior and optionally service host but it is really bad way. The better way is to use Inversion of Control container which will resolve your dependencies from configuration. In that case you will have only one new instance provider, behavior and optionally service host.
Here you have very nice post about creating new instnace provider which resolve services through Unity.