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));
Related
I'm writing a class that works with an API Client object that sometimes becomes corrupted and has to be recreated from inside the object that uses it. What is the best way to do this using Dependency Injection? I'm hesitant to call the DI framework from inside the class since it makes my code dependent on it.
public class MyObject
{
protected IMyAPIClient Client { get; set; }
public MyObject(IMyAPIClient client)
{
Client = client;
}
protected async Task<ReturnType> Run<ReturnType>(Func<Task<ReturnType>> action, int attempt = 1)
{
try
{
return await action();
}
catch(Exception exception)
{
Client = await GetNewClient();
if(attempt > MAX_ATTEMPTS)
{
throw new Exception($"Failed {attempt} times", exception);
}
return await Run(action, attempt++);
}
}
protected async Task<IMyAPIClient> GetNewClient()
{
// what to do here?
}
}
One solution that I came up with was to implement IMyAPIClient in a class that knows the type of IMyAPIClient and recreates it, thus circumventing the DI framework. I wonder if this is sensible or if there is a better way to do it?
I would first try to fix the problems with the ApiClient. Using workarounds for buggy code is rarely a good idea, but might some times be required for third party code. If the problem is in third party code it might also be advisable to put it in a separate process, otherwise you cannot know if failures have some unexpected side-effects.
To create new objects I would suggest injecting a factory of some kind. Exactly how this is done would depend on the DI/IoC framework. Simplest might be a Func<IMyAPIClient>, but an alternative would be an explicit factory-class. You can chose if the factory should use the IoC container to construct the object, or just construct it directly. Also, some IoC framework will handle factories in some special way, while others might require factories to be registered just like everything else. Check the documentation for your framework to see how factories should be managed.
I would also recommend moving the restart logic to a decorator if possible. That way it is separated from the usage, and should be more flexible in case there are multiple users, or the logic needs to be updated. However, registering decorators can be a bit tricky to ensure they are working correctly, but this will also depend on your IoC framework.
I solved the problem by creating a factory class that creates the IMyAPIClient.
This way I can handle the dependency injection in this factory class without making other code dependent on the DI framework.
public class MyObject
{
protected IMyAPIClientFactory ClientFactory { get; set; }
public MyObject(IMyAPIClientFactory clientFactory)
{
ClientFactory = clientFactory;
Client = clientFactory.CreateClient();
}
protected async Task<ReturnType> Run<ReturnType>(Func<Task<ReturnType>> action, int attempt = 1)
{
try
{
return await action();
}
catch(Exception exception)
{
Client = await clientFactory.CreateClient();
if(attempt > MAX_ATTEMPTS)
{
throw new Exception($"Failed {attempt} times", exception);
}
return await Run(action, attempt++);
}
}
}
This question already has answers here:
How do I pass values to the constructor on my wcf service?
(9 answers)
Closed 7 years ago.
I'm building server in C# and WCF. I have my Service and Contract with methods used by Client app. But the whole logic is separated in different class: BusinessLogic. I will inject all I need in BussinessLogic, like repositories/database providers or other data stored in memory. I use Poor man's dependency to build my BussinessLogic (it's my composition root). It's a console application, so BussinessLogic is creaed/resolved in Main(string[] args) method.
My problem is that WCF services are created with parameterless constructor, independent of the rest of the server. They are created every time, when used be the Client.
This is how my server looks like:
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(ServiceLayer), new Uri("net.tcp://localhost:8005"));
host.Open();
Console.WriteLine("Running... Press key to stop");
Console.ReadKey();
}
My services:
[ServiceContract]
public interface IServiceContract
{
[OperationContract]
...
}
public class ServiceLayer : IServiceContract
{
IBusinessLogic _businessLogic;
public ServiceLayer(IBusinessLogic businessLogic)
{
_businessLogic = businessLogic;
}
// Here, I would like to use IBusinessLogic
...
}
I found how to do this using IoC here (I didn't test it tho), but I'm looking for a best solution with Poor man's dependency, without any container or tool, just C# and .NET. If there isn't any solution as good as IoC or close to it, please comment.
If you model your application around commands and queries, it becomes very easy to create your WCF service as a thin maintenance free layer with just one service class.
When you have just one service class, you can use this service class itself as Composition Root or Humble Object and this means you don't need to inject any dependencies into the service class. This prevents you from having to do any integration into the WCF pipeline when it comes to dependency injection, at all!
When you apply these patterns, you can reduce your service to the following code:
[ServiceKnownType(nameof(GetKnownTypes)]
public class CommandService
{
[OperationContract, FaultContract(typeof(ValidationError))]
public void Execute(dynamic command) {
CreateCommandHandler(command.GetType()).Handle(command);
}
public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider cap) {
yield return typeof(ShipOrder);
yield return typeof(CancelOrder);
yield return typeof(ConfirmOrder);
}
// Singletons
private static IUserContext userContext = new WcfUserContext();
private static dynamic CreateCommandHandler(Type commandType)
{
var context = new DbContext();
if (commandType == typeof(ShipOrder))
return Decorate(new ShipOrderHandler(context));
if (commandType == typeof(CancelOrder))
return Decorate(new CancelOrderHandler(context));
if (commandType == typeof(ConfirmOrder))
return Decorate(new ConfirmOrderHandler(context, userContext));
throw new ArgumentException("Unknown: " + commandType.FullName);
}
private static ICommandHandler<T> Decorate<T>(ICommandHandler<T> handler) {
return new WcfExceptionTranslatorCommandHandlerDecorator(
new LoggingCommandHandlerDecorator(
new Logger(),
new AuditTrailingCommandHandlerDecorator(
new PermissionCheckerCommandHandlerDecorator(
new ValidationCommandHandlerDecorator(
new TransactionCommandHandlerDecorator(
handler))))));
}
}
Poor man's DI is now called Pure DI.
You can use Pure DI to compose WCF applications. You need to do that in the Composition Root.
In WCF application, the Composition Root is a custom ServiceHostFactory.
This answer shows an example of how to do that.
You can customize the code in that answer to add more dependencies.
I have a part of my program that sends me an email and/or a push message to my iphone when something occurs. This is done through calls to two seperate WCF services using MSMQ. I followed this guide (model 4.0) in order to make it generic and test friendly. I like the generic channel creation, but my question is wether the proxies and channel factories are really closed/disposed correctly, or if this will blow up when it reaches a 10000 user environment (which it eventually will). The code works perfectly in my 50 user test environment.
Therefore, please review the following code:
Service Proxy
public class ServiceProxy<TChannel> : IServiceProxy<TChannel> where TChannel : ICommunicationObject
{
private readonly TChannel InnerChannel;
public ServiceProxy(TChannel innerChannel)
{
this.InnerChannel = innerChannel;
}
public void Execute(Action<TChannel> operation)
{
try
{
operation(InnerChannel);
InnerChannel.Close();
}
catch (CommunicationException)
{
InnerChannel.Abort();
}
catch (TimeoutException)
{
InnerChannel.Abort();
}
catch (Exception)
{
InnerChannel.Abort();
throw;
}
}
public TResult Execute<TResult>(Func<TChannel, TResult> operation)
{
TResult result = default(TResult);
try
{
result = operation(InnerChannel);
InnerChannel.Close();
}
catch (CommunicationException)
{
InnerChannel.Abort();
}
catch (TimeoutException)
{
InnerChannel.Abort();
}
catch (Exception)
{
InnerChannel.Abort();
throw;
}
return result;
}
}
Service Proxy Factory
public class ServiceProxyFactory : IServiceProxyFactory
{
public IServiceProxy<TChannel> GetProxy<TChannel>(string endpointName) where TChannel : ICommunicationObject
{
var factory = new ChannelFactory<TChannel>(endpointName);
return new ServiceProxy<TChannel>(factory.CreateChannel());
}
}
Making a service call (without return type for simplicity)
public class MessageSender : IMessageSender
{
private const string PushServiceEndpoint = "PushEndpointName";
private const string MailServiceEndpoint = "MailEndpointName";
private readonly IServiceProxyFactory ServiceProxyFactory;
public MessageSender()
{
ServiceProxyFactory = new ServiceProxyFactory();
}
public void NotifyMe(*some args*)
{
ServiceProxyFactory.GetProxy<MailServiceChannel>(MailServiceEndpoint)
.Execute(a => a.SendEmail(*some args*));
}
The questions are:
Should I close the ServiceProxy after the Execute?
Is it wise to create a ChannelFactory every time I call GetProxy(), and should this ChannelFactory then be closed again if so?
Is it really performance friendly to generate a ServiceProxy for every call? (it seems really heavy to me, but maybe someone can prove me wrong).
I left the interfaces out from this post, but they are really simple, and this whole setup with proxies and interfaces works really well with unit and integration testing.
I hope some of you coding wizards have an opinion about this, and will share this.
Thanks in advance!
The main performance impact has the creation of a ChannelFactory.
Creating ChannelFactory instances incurs some overhead because it involves the following operations:
Constructing the ContractDescription tree
Reflecting all of the required CLR types
Constructing the channel stack
Disposing of resources
https://msdn.microsoft.com/en-us/library/hh314046%28v=vs.110%29.aspx
WCF team has implemented caching for ClientBase<TChannel> class, it is suitable when you have auto generated proxy classes.
As you are using pure ChannelFactory you have to be careful about creating factories it on each call in order to have a better performance.
A good solution would be to implement caching of ChannelFactory<TChannel> your own (there is a good idea on how to do that). So at the end in your ServiceProxyFactory instead of having new ChannelFactory<TChannel>(endpointName); you should use cached instances like CachedChannelFactory<TChannel>.GetInstance().
Edit: There is another good article written by Michele Leroux Bustamante, that explains when To Cache or Not to Cache
I just wanted to hear your Opinion about a WCF Client implementation.
I have an Server that provides several services like SecurityManager.
This service is defined in the Interface ISecurityManager and implemented in the Class SecurityManager.
So far everything is fine.
On the Client side I want to implement the services calls via a seperated Class. My question is whether I do this also in an SecurityManager Class which implements the same ISecurityManager Interface?
What is here the best practise?
Visual Studio Generator
You can ask Visual Studio to build a client for you, right-clicking your client project and adding a Service Reference. There's a dialog where you can either type your service url or discover it from within the solution.
Creating a Client
You can build the client class inheriting from ClientBase<ISecurityManager>, ISecurityManager. Being an operation example on this client class:
public void ExampleMethod(int id)
{
Channel.ExampleMethod(id);
}
Like a real man does
Or without any client class, just calling it:
ServiceInvokerinvoker invoker = new ServiceInvoker();
var result = invoker.InvokeService<ISecurityManager, ReturnType>( proxy => proxy.ExampleMethod(1) );
Last two options assuming you already have configured the ISecurityManager client:
<client>
<endpoint name="ServiceName"
address="http://ServiceName.test/Service"
binding="basicHttpBinding"
contract="ISecurityManager" />
</client>
I would suggest to use a generic Wrapper make WCF calls.
So everytime you need to make a WCF call you can do it like this:
var invoker = new ServiceInvoker();
var result = invoker.InvokeService<ISecurityManager, MyObjectReturnType>(
proxy => proxy.DoSomething(myParameters));
return result;
I use ServiceInvoker to create the channel and manage any exceptions that would occur inside. It creates a channel with the ISecurityManager contract, with return type of MyObjectReturnType and with the action DoSomething (method from ISecurityManager contract).
You can use this solution with all your interfaces, without any extra class implementation!
InvokeService would be something like this:
public TResult InvokeService<TServiceContract, TResult>(Func<TServiceContract, TResult> invokeHandler) where TServiceContract : class
{
ICommunicationObject communicationObject;
var arg = CreateCommunicationObject<TServiceContract>(out communicationObject);
var result = default(TResult);
try
{
result = invokeHandler(arg);
}
catch (Exception ex)
{
Logger.Log(ex);
throw;
}
finally
{
try
{
if (communicationObject.State != CommunicationState.Faulted)
communicationObject.Close();
}
catch
{
communicationObject.Abort();
}
}
return result;
}
private TServiceContract CreateCommunicationObject<TServiceContract>(out ICommunicationObject communicationObject)
where TServiceContract : class
{
//Create the Channel
// ICommunicationObject is an out parameter for disposing purposes
return channel;
}
To implement the service calls "via a separate class" you can just generate a service reference using svcutil.exe or visual studio from a running instance of your service.
This will generate a set of types off your service contract which will be completely "separate" from the assemblies containing your service contract and implementation.
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 :-)