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
Related
I'm using Autofac with WCF integration in a project. I'm trying to figure out a way to lazy initialize data contract proxy collection properties to avoid transferring entire object graphs across the wire.
My current plan is to inject the WCF service in each deserialized data contract so they call the service, get the collection property data and initializes it.
My question is: Is there a way to tell Autofac to inject services in each data contract proxy deserialized at the client? Like some tweaking at the DataContractSerializer or something.
(No service locator, please...)
Thanks!
Unfortunately there is nothing like this available "out of the box" with Autofac. There is something similar in Autofac's MVC integration, but that's because MVC has a more specific integration point for that sort of thing (IActionInvoker).
You might be able to write a custom client-side behavior that intercepts certain known types (like collections) on the client and swaps in a lazy-initialized collection. There's a similar question here asking about how to swap the DataContractSerializer out at runtime. You could use a mechanism like that.
I have a WCF service application (actually, it uses WCF Web API preview 5) that intercepts each request and extracts several header values passed from the client. The idea is that the 'interceptor' will extract these values and setup a ClientContext object that is then globally available within the application for the duration of the request. The server is stateless, so the context is per-call.
My problem is that the application uses IoC (Unity) for dependency injection so there is no use of singleton's, etc. Any class that needs to use the context receives it via DI.
So, how do I 'dynamically' create a new context object for each request and make sure that it is used by the container for the duration of that request? I also need to be sure that it is completely thread-safe in that each request is truly using the correct instance.
UPDATE
So I realize as I look into the suggestions below that part of my problem is encapsulation. The idea is that the interface used for the context (IClientContext) contains only read-only properties so that the rest of the application code doesn't have the ability to make changes. (And in a team development environment, if the code allows it, someone will inevitably do it.)
As a result, in my message handler that intercepts the request, I can get an instance of the type implementing the interface from the container but I can't make use of it. I still want to only expose a read-only interface to all other code but need a way to set the property values. Any ideas?
I'm considering implementing two interfaces, one that provides read-only access and one that allows me to initialize the instance. Or casting the resolved object to a type that allows me to set the values. Unfortunately, this isn't fool-proof either but unless someone has a better idea, it might be the best I can do.
Read Andrew Oakley's Blog on WCF specific lifetime managers. He creates a UnityOperationContextLifetimeManager:
we came up with the idea to build a Unity lifetime manager tied to
WCF's OperationContext. That way, our container objects would live
only for the lifetime of the request...
Configure your context class with that lifetime manager and then just resolve it. It should give you an "operation singleton".
Sounds like you need a Unity LifetimeManager. See this SO question or this MSDN article.
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 have a c# solution with 3 projects - Data, WCF and UI. The first one is a class library that talks to db. It's exposed via the second one, which is of type WCF Service Library - the reason for that is it will be exposed in third project - Asp.net app called UI - as a simple svc pointing to dll.
Just to point it out, I'm not using Repository pattern.
I need to have ISession for a WCF call (similiar to Session-per-request approach for asp.net). Can anyone share a solution that simply works? I don't want to use any IOC for that.
Use WcfOperationSessionContext (new in 3.0).
Once bound, your Data classes just have to use SessionFactory.GetCurrentSession().
Each call to service is associated with unique OperationContext. OperationContext doesn't have any store for custom objects but you can implement extension. By setting session in MessageInspector you can initiate NHibernate Session per call in centralized place and access your extended context in any operation.
I'm writing a WCF service and want to expose some custom configuration elements (e.g. Custom ConfigurationSection and ConnectionStringSettings) so that I can modify the service's configuration.
One of my custom configuration elements inherits from System.Configuration.ConfigurationElementCollection. When I try to start my WCF service I get the following error message...
Type 'System.Configuration.ConfigurationElementCollection' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute.
Is there a way to implement the DataContract for this Type? I have my inherited class marked with the [DataContract] attribute.
Just hit this issue today. It was confusing because the problem came up moving a project from machine to machine. This article seems relevant:
http://blogs.msdn.com/youssefm/archive/2009/08/10/serializing-plain-old-clr-objects-poco-types-with-datacontractserializer.aspx
To summarize in case of link rot, the issue seems to emerge in runtime 3.5 and go away in runtime 3.5 SP1.
Ok, well in the end I had to re-architect my solution. I found the SerializableConfigurationSection most beneficial. It's in the patterns and practices EnterpriseLibrary. So rather than trying to pass my Custom Configuration Sections through WCF, I perform the seralization/deserialization manually and pass the configuration sections through WCF as a string.