using ninject with a remoting server - c#

I have a class Server that implements interface IServer that is accessible using .net remoting (i have no chioce on the matter JICYAW).
internally this server uses other classes to implement logic and data access.
this server class has constructor injected dependencies that it needs to do its job.
when a client calls in (per call) the remoting framework will instatiate a Server instance using a parameterless constructor and not (of course) using Ninject.
how can i get Ninject to be the one in charge for new'ing up the class ?
i have seen this similar SO question but this isnt relevant for Ninject.
thanks for your help

You can create a service facade that will be called by the client. This facade will internally call your container to resolve the real service. For instance:
public class ServiceFacade : IService
{
private readonly IService service;
// default constructor
public ServiceFacade()
{
this.service = YourContainer.Current.Resolve<IService>();
}
void IService.ServiceOperation()
{
this.service.ServiceOperation();
}
}

What might work is to intercept the calls to those objects using a proxy and forward the calls to the real object. Note that I'm not very experienced with this, so I'm not sure if this actually works, but here goes:
public class DependencyInjectionProxy : RealProxy
{
private object realInstance;
public DependencyInjectionProxy(Type classToProxy,
object realInstance) : base(classToProxy)
{
this.realInstance = realInstance;
}
public static T MakeProxy<T>(T realInstance)
{
return (T)(new DependencyInjectionProxy(typeof(T),
realInstance).GetTransparentProxy());
}
public override IMessage Invoke(IMessage msg)
{
if (msg is IMethodCallMessage)
{
var message = (IMethodCallMessage)msg;
object value = message.MethodBase.Invoke(
this.realInstance, message.Args);
Console.WriteLine(value);
return new ReturnMessage(value, null, 0, null, message);
}
return msg;
}
}
This works when you do something like this:
var container = new YourContainer();
container.RegisterSingle<IService, Service>();
IService proxy = DependencyInjectionProxy.MakeProxy<IService>(
container.Resolve<IService>());
proxy.SomeMethod();
This works great, but to be honest, I have no idea how to configure this in a way that you can intercept incoming calls this way. Somewhere you need to register your DependencyInjectionProxy, but that's where my experience with remoting stops :-)

Related

Passing a unique value to all classes using Dependency Injection?

The following code shows the flow I’m currently trying to implement within a WCF service. The service on startup calls the Bootstrapper class which uses Unity to register and resolve the required types. The Gateway class contains the public method which then kicks off the main flow of processing a message (there are many more levels to the code than is shown below).
public static class Bootstrapper
{
public static IGateway InitializeGateway()
{
IUnityContainer resolver = new UnityContainer();
resolver.RegisterType<IGateway, Gateway>();
resolver.RegisterType<ITranslator, Translator>();
resolver.RegisterType<IFormatter, IFormatter>();
return resolver.Resolve<IGateway>();
}
}
public class Gateway : IGateway
{
private readonly ITranslator translator;
private readonly IFormatter formatter;
public Gateway(ITranslator translator, IFormatter formatter)
{
this.translator = translator;
this.formatter = formatter;
}
public string ProcessMessage(string requestMessage)
{
// Create a new GUID for use in main flow for logging
Guid messageGuid = Guid.NewGuid();
requestMessage = this.translator.TranslateMessage(requestMessage);
requestMessage = this.formatter.FormatMessage(requestMessage);
return requestMessage;
}
}
Now what I’m trying to achieve is take the GUID (created for each message) and pass this down within the flow of the service such that each class has a reference to it for logging purposes.
I have tried to find a way of using DI and constructor injection but don’t know if this can be done as the GUID is created on receipt of a message by the gateway (after the bootstrapper call). What I’m trying to get away from is passing the GUID into each method as a parameter.
Any suggestions?
Instead of rolling your own solution to this problem with DI, I would recommend you use the thread-static property Trace.CorrelationManager.ActivityId for this purpose.
Take a look at this article on WCF End-To-End Tracing.

Autofac WCF Integration - Resolve dependencies based on request data

How can I configure an Autofac container so it resolves the dependencies of a WCF service based on properties values of the operation-parameter (request object)?
For example, given this data contract...
[DataContract]
public class MyRequest
{
[DataMember]
public bool MyBool { get; set; }
}
this WCF service...
public class MyWcfService : IWcfService
{
private IService m_service;
public MyWcfService(IService service)
{
m_service = service;
}
public virtual MyResponse Operation(MyRequest request) { }
}
and these dependencies...
public interface IService { }
public class TypeA : IService { }
public class TypeB : IService { }
I would like the container to resolve TypeA if MyBool equals true and TypeB otherwise. Is that feature available? Should I approach the problem differently?
Constraints:
Avoiding the Autofac.Extras.Multitenant package is a plus.
Keeping the signature of the service constructor unchanged is also desired. (See my answer below)
There are a few ways to achieve this. One of the ways is to use IIndex<K,V>. It's built-in "lookup" feature that chooses between service implementations based on a key. You can find more info on Autofac's wiki page. An example code could look like:
// Register your dependency with a key, for example a bool flag
builder.RegisterType<TypeA>().Keyed<IService>(true);
builder.RegisterType<TypeB>().Keyed<IService>(false);
// Your service could look like:
public class MyWcfService
{
private readonly IIndex<bool, IService> _services;
// Inject IIndex<Key,Value> into the constructor, Autofac will handle it automatically
public MyWcfService(IIndex<bool, IService> services)
{
_services = services;
}
public virtual void Operation(MyRequest request)
{
// Get the service that you need by the key
var service = _services[request.MyBool];
}
}
Another approach is to use Metadata feature. More information on wiki page.
Option 1 - Using Autofac:
The Autofac instance provider that creates your service instance does not use or pass along the operation's message. Here's the latest implementation of the method in Autofac. Notice the message parameter is unused.
public class AutofacInstanceProvider : IInstanceProvider
{
// lots of code removed...
public object GetInstance(InstanceContext instanceContext, Message message)
{
if (instanceContext == null)
{
throw new ArgumentNullException("instanceContext");
}
var extension = new AutofacInstanceContext(_rootLifetimeScope);
instanceContext.Extensions.Add(extension);
return extension.Resolve(_serviceData);
}
}
So to get the behavior you want with existing Autofac code, you'll need to inject the dependency into your class using something other than constructor injection, which is #Alexandr Nikitin's solution. This is reasonable, but I agree with the comment "not loving it".
Option 2 - A Custom IInstanceProvider:
Writing a custom WCF IInstanceProvider is a reasonable option, but it will be a lot of code.
The good news is that the code in Autoface.Integration.WCF is a nice example and you could plug your implementation into Autofac.
The bad news is that Autofac.Integration.WCF code doesn't itself use dependency injection. For example AutofacDependencyInjectionServiceBehavior directly calls var instanceProvider = new AutofacInstanceProvider(_rootLifetimeScope, _serviceData). As a result you'll you have to implement a replacement for AutofacInstanceProvider, AutofacDependencyInjectionServiceBehavior, AutofacHostFactory, and probably more. Then you'll need to create an extension for the AutofacInstanceContext to contain the information read from the message. Its a lot of code.
If you are going to do the custom IInstanceProvider I suggest reading up on Carlos Figueira's blog:
WCF Extensibility – IInstanceProvider - for good background
WCF Extensibility – Message Inspectors - Search for the section that starts with WCF Message objects can only be “consumed once". You'll need to follow these rules when inspecting the message.

Object and a web service dependency

I have a question about implementing the Dependency Injection pattern. I have a class that requires access to a web service. According to this pattern I shouldn't have my class instantiating the service as this causes a strong dependency with it. This lead me to creating a factory class that constructs my class and in its constructor passing the correct service it requires, i.e. dependencies.
What is troubling to me is that I am passing the instance of the web service client to my object but wouldn't this leave the service open?
Should I pass the entire client in as opposed to only the interface? This way I can implement IDisposable and close the connection to the service?
Thanks in advance.
Please feel free to correct any terminology, don't mean to cause confusion.
For example:
public class ProductService
{
private IProductService client;
public ProductService(IProductService client)
{
this.client = client;
}
public void DoIt()
{
client.MyWebMethod();
}
}
public class Factory
{
public static T Create<T>() where T : class
{
T item = null;
if (typeof(T) == typeof(ProductService))
{
item = new CustomerService(**new ProducttServiceClient()**) as T;
}
return item;
}
}
Yes, if you create instance yourself by new ProducttServiceClient(), then you/factory need to dispose it. That's the place where DI containers like Unity, Castle Windsor can help you and release/dispose it.
Assuming we are talking about generated service client ProducttServiceClient - subclass of ClientBase, please be aware, that if you dispose the client it will try to close opened and not aborted channels - which can lead to an exception.See this link for details
If you just pass in opened channel (System.ServiceModel.ClientBase.CreateChannel()), then you can close/abort it and reuse the client again.
Yes, if your factory class creates the service client instance, it should also be responsible for closing it. But what are you trying to achieve (except trying out dependency injection and the factory pattern)? I don't think the factory pattern gives you much in this case.
If you don't want your client to create and close the proxy every time you want to call a service operation I would recommend creating a extension method on ICommunicationObject that is responsible to do the work and then close the proxy. Then you only have to implement the logic for disposing your client once (and in one place!).
extension might look like this:
public static TResult Using<T, TResult>(this T client, Func<T, TResult> work) where T : ICommunicationObject
{
TResult res = default(TResult);
try
{
res = work(client);
client.Close();
}
catch (CommunicationException)
{
client.Abort();
throw;
} // ... more catch cases might go here...
finally
{
if (client.State != CommunicationState.Closed)
client.Abort();
}
return res;
}
your client would invoke the method like this:
using TheNameOfYourNamespaceDefiningTheExtension
return new ServiceClient().Using(client => client.MethodName(request));

Testing IDisposable and WCF client

Usually I have client code similiar to something like this:
// SomeOtherServiceClient would be injected in actual code.
ISomeOtherService client = new SomeOtherServiceClient();
... so that I can mock the service for testing. But now I have a WCF service that has the context mode set to PerSession and implements IDisposable.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class SampleService : ISampleService, IDisposable
{
public void SampleMethod() { ... }
public void Dispose() { ... }
}
If I wish to put the client inside a using statement, is there still a way for me to mock the client for testing?
// SampleServiceClient would be injected in actual code.
using (var client = new SampleServiceClient())
{
...
}
If I understand the problem, it is that ISomeOtherService is a WCF service contract, and does not implement IDisposable even though all implementing clients will. You can get around this by changing the using statement to something like this:
public void SampleMethod()
{
//client was injected somehow
using(this.client as IDisposable)
{
...
}
}

Dependency Injection wcf

I want inject a implementation of my Interface in the WCF but I want initialize my container of Dependency Injection in the Client of the WCF. So I can have a different implementation for each client of the my service.
When you use svcutil.exe or the Add Service Reference wizard in Visual Studio, one of the many types auto-generated will be a client interface. Let's call it IMyService. There will also be another auto-generated interface called something like IMyServiceChannel that implements IMyService and IDisposable. Use this abstraction in the rest of your client application.
Since you want to be able to create a new channel and close it again, you can introduce an Abstract Factory:
public interface IMyServiceFactory
{
IMyServiceChannel CreateChannel();
}
In the rest of your client application, you can take a dependency on IMyServiceFactory:
public class MyClient
{
private readonly IMyServiceFactory factory;
public MyClient(IMyServiceFactory factory)
{
if (factory == null)
{
throw new ArgumentNullException("factory");
}
this.factory = factory;
}
// Use the WCF proxy
public string Foo(string bar)
{
using(var proxy = this.factory.CreateChannel())
{
return proxy.Foo(bar);
}
}
}
You can create a concrete implementation of IMyServiceFactory that wraps WCF's ChannelFactory<T> as an implementation:
public MyServiceFactory : IMyServiceFactory
{
public IMServiceChannel CreateChannel()
{
return new ChannelFactory<IMyServiceChannel>().CreateChannel();
}
}
You can now configure your DI Container by mapping IMyServiceFactory to MyServiceFactory. Here's how it's done in Castle Windsor:
container.Register(Component
.For<IMyServiceFactory>()
.ImplementedBy<MyServiceFactory>());
Bonus info: Here's how to wire up a WCF service with a DI Container.
Here is what I understand from your question:
You have an interface that is not related to WCF. Let's call it IInterface
You have a WCF client that used a service. Let's call the service contract: IService
you want the ServiceClient class that by default implements the IService when you add a service reference also to implement IInterface.
IF this is the case, you can use the fact that the ServiceClient class is marked as partial.
Just make another partial declaration for ServiceClient and add the interface you need (You have to make sure that the namespaces are equal for the auto-generated code and your code). It should look somthing like:
namespace [ServiceClient Namespace]
{
public partial class ServiceClient : IInterface
{
}
}
Hope it helped.

Categories