I have an existing Structuremap ApplicationRegistry that relies on HttpContext.Current.Server and also HttpContext.Current.Items (via HttpContextScoped). I'd like to use this in my WCF ServiceHostFactory, but HttpContext.Current remains belligerently null.
I am using basicHttpBinding and for the scope of the project I'm working on I'm happy to continue to rely on that being used. My understanding is that if you use basicHttpBinding you should be able to use HttpContext.Current. Since this is always null I've obviously missed something.
What might that be?
The solution was to add this attribute to my service class:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
Related
I have a .NET 4 WCF service (MEX and HttpGET).
For the HttpGET endpoint, I would like to override the default MessageFormatter.DeserializeRequest to map UriTemplate to strongly-typed objects.
Ideally, a custom attribute would be used to decorate the methods that should use this formatter, but I'm not sure whether I can switch the formatter in that regard.
Is this doable, and can someone walk me through the configuration needed in app.config?
If you want fine grained formatting control for WCF REST, I'd suggest one of the following two options:
Override WebHttpBehavior to specify your own message formatter. This gives you a lot of control, but requires a lot of legwork. http://msdn.microsoft.com/en-us/library/system.servicemodel.description.webhttpbehavior.getrequestclientformatter.aspx
Use the new WCF Web API, which offers much more configurability for REST services. http://wcf.codeplex.com/wikipage?title=WCF%20HTTP.
However, if ALL you want to do is map certain query string parameters to strongly typed objects, you can just implement your own QueryStringConverter class :
http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.querystringconverter.aspx
and use that in your custom WebHttpBehavior:
http://msdn.microsoft.com/en-us/library/system.servicemodel.description.webhttpbehavior.getrequestclientformatter.aspx ).
I'm trying to have Castle (3.0) inject constructor params into a WCF service, like this
ServiceHostBase clientServiceHost = new Castle.Facilities.WcfIntegration.DefaultServiceHostFactory()
.CreateServiceHost(typeof(IClientExchange).AssemblyQualifiedName, new Uri[0]);
However I get the following exception 'The service type provided could not be loaded as a service because it does not have a default (parameter-less) constructor.'
The service impl of type ClientExchange takes a constructor param of type IProviders
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class ClientExchangeService : ExchangeService, IClientExchange
{
public ClientExchangeService(IProviders providers)
: base(providers) { }
}
My windsor installer looks like this:
container.AddFacility<WcfFacility>()
.Register
(
Component.For<IProviders>().Instance(Providers.DbInstance),
Component.For<IClientExchange>().ImplementedBy<ClientExchangeService>(),
);
At the moment it seems like WCF is trying to new up the service without castle providing the dependency. Tried a few alternative examples out there but many are for previous versions of castle pre 3.0. I must be missing a hook somewhere? How do I tell WCF to defer construction responsibility to castle?
I think this: how do i pass values to the constructor on my wcf service might be the answer to your problem. Or, for something more Windsor specific this might help: Dependency Injection in WCF Using Castle Windsor.
UPDATE
OK, so I think I have figured this out. First of all the problem is this attribute:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
If you do not specify that Windsor will be able to inject the dependencies into the constructor perfectly fine - with that it cannot.
From looking at the description of that attribute here I see that you want your service to be a singleton so since that is the default for Windsor you can simply remove that attribute and it should start working for you and behave as you expect.
There are two other lifestyles that you may be interested in that are specifically for WCF:
LifestylePerWcfOperation()
LifestylePerWcfSession()
(specify them in the normal place - more information is available here)
Incidentally, you do not have to do the ServiceHostBase stuff at all, instead you can use the AsWcfService extension method like so (personally I prefer this way of doing it):
container
.AddFacility<WcfFacility>(f => f.CloseTimeout = TimeSpan.Zero)
.Register(
Component
.For<IProviders>()
.Instance(Providers.DbInstance),
Component
.For<IClientExchange>()
.ImplementedBy<ClientExchangeService>()
.AsWcfService(new DefaultServiceModel()
.AddEndpoints(WcfEndpoint
.BoundTo(new BasicHttpBinding())
.At("http://localhost:8000/ClientExchangeService"))));
I am building a WCF Rest Service using VS2010 .net 4.0 and the Rest service template. I would like to introduce spring.net - IoC but I am not able to get spring initialized when the InstanceContextMode.Single is set. For all other settings I can use IInstanceProvider interface and introduce a custom behaviour.
My question is:
Is there any other way I can get spring initialized?
Sorry I just saw the comments in the main response
If your only problem is the name of the reference, you could create your own and fix the reference parameter, or add a dictionary where you set some aliases in the xml config and do a lookup against that.
As far as I know you can't use Spring when the InstanceContextMode is single; from the doc:
While integrating 'natively' with WCF does seem to be the most natural
approach there is one 'gotya' that needs to be investigated further to
see if there is an acceptable workaround in order for this approach to
be viable. The issue is that if the service is configured to be a
singleton, for example using
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)] then
the invocation of the IInstanceProvider is short-circuited.
The documentation suggests this:
One workaround, which is not very appealing, is to use the PerCall instancing mode but set the
singleton attribute in the Spring configuration to true, this way the
same instance is always returned.
More info here: http://www.springframework.net/docs/1.2.0-M1/reference/html/wcf.html
within our per-session WCF services hosted in ISS, we would like to use Ninject to IOC different data access component through the interface.
Where would be the best place to declare the binding once? is it in Application_Start of Global.asax?
If it is, how could I obtain the instance through the inferface from Ninject?
I know in StructureMap, we can call something like ObjectFactory.GetInstance()?
What is the equivalent in Ninject?
Thanks
I assume you have looked at the official WCF extension? I usually define my own service factory (referenced in the .SVC file) and reference my Ninject module from there.
As for getting an instance from an interface (i.e. the opposite of having it injected), you do so via the kernel. (You can always have an instance of IKernel injected into any of your classes by adding it to your constructor.) Once you have it, you just use:
kernel.Get<IYourInterface>();
I'm trying to hock up WCF with dependency injection. All the examples that I have found is based on the assumptions that you either uses a .svc (ServiceHostFactory) service or uses app.config to configure the container. Other examples is also based on that the container is passed around to the classes.
I would like a solution where the container is not passed around (not tightly coupled to Unity). Where I don't uses a config file to configure the container and where I use self-hosted services.
The problem is - as I see it - that the ServiceHost is taking the type of the service implementation as a parameter so what different does it do to use the InstanceProvider?
The solution I have come up with at the moment is to register the ServiceHost (or a specialization) an register a Type with a name ( e.g. container.RegisterInstance<Type>("ServiceName", typeof(Service);).
And then container.RegisterType<UnityServiceHost>(new InjectionConstructor(new ResolvedParameter<Type>("ServiceName"))); to register the ServiceHost.
Any better solutions out there? I'm I perhaps way of in my assumptions.
Best regards,
Michael
Use Constructor Injection to wire up your service implementation, just like you would with any other class.
Here's a writeup on how to make WCF understand Constructor Injection.
The example in that answer demonstrates Poor Man's Injection, but you can extrapolate from it and set up your UnityContainer instance in the ServiceHostFactory instead of a hard-coded dependency.
You pass the container instance all the way to the custom IInstanceProvider. Now you can use the container in the GetInstance method:
public object GetInstance(InstanceContext instanceContext)
{
var serviceType = instanceContext.Host.Description.ServiceType;
return this.container.Resolve(serviceType);
}