I've got a simple decorator class like the following. Notice how my public methods all create a new instance of the to-be-decorated class, then forward the call to that instance.
The problem with this class is that whenever IMyService gets updated, I have to update this proxy class too.
public class MyProxyService : IMyService
{
readonly IMyServiceFactory _realServiceFactory;
public MyProxyService(IMyServiceFactory realServiceFactory)
{
_realServiceFactory = realServiceFactory;
}
private IMyService CreateRealService()
{
return _realServiceFactory.CreateRealService();
}
public int A()
{
return CreateRealService().A();
}
public int B(int b1)
{
return CreateRealService().B(int b1);
}
public int C(int c1, int c2)
{
return CreateRealService().C(c1,c2);
}
public int D(int d1, int d2, int d3)
{
return CreateRealService().D(d1,d2,d3);
}
public void E()
{
CreateRealService().E();
}
}
I've tried creating a dynamic version using Castle.DynamicProxy, without any luck so far.
Anyone know a good, simple way to dynamically create a decorator like this?
I was able to get this to work using DynamicProxy.ProxyGenerator's CreateInterfaceProxyWithTargetInterface(..) .
I first created a dynamic proxy factory. This returns a proxy object, for which each method will be intercepted by the provided IInterceptor:
public class MyDynamicallyDecoratedServiceClientFactory
{
readonly ProxyGenerator _proxyGenerator;
readonly IInterceptor _interceptor;
public MyServiceClientFactory(IInterceptor interceptor)
{
_interceptor = interceptor;
_proxyGenerator = new ProxyGenerator();
}
public IMyService Create()
{
IMyService proxy = _proxyGenerator.CreateInterfaceProxyWithTargetInterface<IMyService>(null, _interceptor);
return proxy;
}
}
I then implemented the interceptor. Upon each method call, this interceptor will be called, which will create a new IMyService from the provided IMyServiceFactory, and delegate the method call to that new instance.
public class MyServiceClientInterceptor : IInterceptor
{
readonly IMyServiceFactory _svcFactory;
public MyServiceClientInterceptor(IMyServiceFactory svcFactory)
{
_svcFactory = svcFactory;
}
public void Intercept(IInvocation invocation)
{
IMyService realService = _svcFactory.Create();
IChangeProxyTarget changeProxyTarget = invocation as IChangeProxyTarget;
changeProxyTarget.ChangeInvocationTarget(realService);
invocation.Proceed();
}
}
Finally, to make use of all this:
// Create a service factory (the to-be-decorated class)
IMyServiceFactory myRealServiceFactory = /* ... */;
// Create a factory that will create decorated services
MyServiceClientInterceptor interceptor =
new MyServiceClientInterceptor(myRealServiceFactory);
MyDynamicallyDecoratedServiceClientFactory svcFactory =
new MyDynamicallyDecoratedServiceClientFactory(interceptor);
// Create a service client
IMyService svc = svcFactory.Create();
// Use it!
svcProxy.A();
Related
Is there a way the tell the ActivatorUtilities.CreateInstance<T>(IServiceProvider serviceProvider); method to try to use other constructors if the first one can't be constructed?
I have a class with multiple constructors:
public ViewModelB(SomeDependency someDependency): this one only takes SomeDependency which is registered in a DI container
public ViewModelB(SomeDependency someDependency, GetUserRequest request): this one takes SomeDependency which is registered in a DI container and a GetUserRequest which has to be passed in manually
And I'm trying to activate them and resolve dependencies like so:
IServiceProvider serviceProvider; //this gets passed from somewhere
Guid userId; //this gets passed manually by the caller
//works
var instanceAWithoutParams = ActivatorUtilities.CreateInstance<ViewModelA>(serviceProvider);
//works
var instanceAWithParams = ActivatorUtilities.CreateInstance<ViewModelA>(serviceProvider, new[] { new GetUserRequest { UserId = userId } });
//does NOT work, it tries to use the first constructor and fails
var instanceBWithoutParams = ActivatorUtilities.CreateInstance<ViewModelB>(serviceProvider);
//works
var instanceBWithParams = ActivatorUtilities.CreateInstance<ViewModelB>(serviceProvider,, new[] { new GetUserRequest { UserId = userId } });
The activation of instanceBWithoutParams fails because it can't resolve the request parameter. It tries to use the first constructor and doesn't check other ones when the activation fails.
Here's what the services look like, they're the same with one difference: the order of the constructors.
public class ViewModelA
{
private readonly SomeDependency _someDependency;
private readonly GetUserRequest? _request;
public ViewModelA(SomeDependency someDependency)
{
_someDependency = someDependency;
}
public ViewModelA(SomeDependency someDependency, GetUserRequest request)
{
_someDependency = someDependency;
_request = request;
}
}
public class ViewModelB
{
private readonly SomeDependency _someDependency;
private readonly GetUserRequest? _request;
public ViewModelB(SomeDependency someDependency, GetUserRequest request)
{
_someDependency = someDependency;
_request = request;
}
public ViewModelB(SomeDependency someDependency)
{
_someDependency = someDependency;
}
}
public class GetUserRequest
{
public Guid UserId { get; set; }
}
Thanks.
I struggled with the same issue. Eventually I came up with this solution:
I would use something like a factory which is able to construct ServiceB by calling a method.
For example:
var serviceBFactory = ActivatorUtilities.CreateInstance<ServiceBFactory>(serviceProvider);
var instanceBWithoutParams = serviceBFactory.CreateServiceB();
var instanceBWithParams = serviceBFactory.CreateServiceB(new Request());
This way you keep you DI clean. But this means that the ServiceBFactory need to know which services need to be injected in a ServiceB. (so that will be a tight coupling) They come as a package.
I've chosen to re-design the view models instead of trying to pass optional parameters next to services from DI (thanks to Steven for the helpful articles: 1 and 2).
There also seems to be no way of making the ActivatorUtilities.CreateInstance<T>(IServiceProvider serviceProvider); method try other constructors after one fails, so here's what my edited solution looks like.
I've moved the initialization of the optional parameter out of the constructor, that way I only have one constructor that only takes injectables. The parameter is then passed separately via the TakeParameter method. The only downside I can think of is that the parameter can no longer be readonly and I can live with that.
My custom activator utility:
public interface IAcceptParameter<T>
{
void TakeParameter(T parameter);
}
public static class CustomActivator
{
public static T CreateInstance<T>()
{
return ActivatorUtilities.CreateInstance<T>(_serviceProvider);
}
public static T CreateInstanceWithParam<T, K>(K parameter) where T : IAcceptParameter<K>
{
var instance = ActivatorUtilities.CreateInstance<T>(_serviceProvider);
instance.TakeParameter(parameter);
return instance;
}
}
Changed view model
public class SomeViewModel : IAcceptParameter<Guid>
{
private readonly SomeDependency _someDependency;
private Guid? _userId;
public SomeViewModel(SomeDependency someDependency)
{
_someDependency = someDependency;
}
public void TakeParameter(Guid parameter){
_userId = parameter;
}
}
How I use it
var instanceWithoutParam = CustomActivator.CreateInstance<SomeViewModel>(serviceProvider);
Guid userId;
var instanceWithParam = CustomActivator.CreateInstanceWithParam<SomeViewModel, Guid>(serviceProvider, userId);
Let say you have a class like this:
public class a
{
public string p { get; set; }
public a()
{
p = "default constructor";
}
public a(string pv)
{
p = pv;
}
}
You can use .GetConstructor method to use a specific constructor:
public class Program
{
static void Main(string[] args)
{
var c = typeof(a).GetConstructor(new Type[] { typeof(string) });
if (c != null)
{
var myA = (a)c.Invoke(new object[] { "new value" });
Console.WriteLine($"Value of p is {myA.p}");
}
}
}
I have an interface Arbiter
public interface Arbiter
{
ContextData GetContextData();
}
I have a class that implements this interface.
public class ContextArbiter : Arbiter
{
ContextData m_data;
public CMBusContextArbiter()
:
base()
{
m_data = new ContextData();
}
public ContextData GetContextData()
{
return m_data;
}
}
I have another class that uses this interface
public class SelectData
{
private Arbiter m_Arbiter;
public SelectData(Arbiter Arbiter)
{
m_Arbiter = Arbiter;
}
public string RetrieveId()
{
return m_Arbiter.GetContextData().RouteId;
}
}
Now I want to unit test this class
public class SelectDataTest : UnitTestBase
{
private Mock<Arbiter> Arbiter;
private SelectData SelectData;
[OneTimeSetUp]
public void OneTimeSetup()
{
Arbiter= new Mock<Arbiter>();
SelectData = new SelectData(Arbiter);
}
}
But it seems that I can't pass the mock object to the SelectData class. It shows
Cannot convert Moq.Mock to Arbiter.
How can I get around this issue.
Use the Object property of the Mock<T> class to access the mocked object.
//...
Arbiter = new Mock<Arbiter>();
SelectData = new SelectData(Arbiter.Object);
//...
Reference Moq Quickstart
In brief: I want resolve interface by prop in entity.
I have self hosted wcf and use ninject for DI.
My working code for example:
//program.cs
...
private static StandardKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<IDbConnectionFactory>().ToMethod(c =>
new OrmLiteConnectionFactory(
conString,
SqlServerDialect.Provider))
.InSingletonScope();
kernel.Bind<IControllerProccessor>().To<ControllerProccessor>()
.WhenInjectedInto<HelloWorldService>().WithConstructorArgument(kernel);
kernel.Bind<IControllerProccessor>().To<Vendor1Proccessor>()
.Named("vendor1");
kernel.Bind<IControllerProccessor>().To<Vendor2Proccessor>()
.Named("vendor2");
return kernel;
}
...
//IControllerProccessor.cs
public interface IControllerProccessor
{
SimpleController Ctr { get; set; }
bool sendMsg(string msg);
}
//Vendor1Proccessor.cs
public class Vendor1Proccessor : IControllerProccessor
{
public SimpleController Ctr {get; set;}
public bool sendMsg(string msg)
{
//specific to vendor code, for example calls to vendor1 SDK
Console.WriteLine("Controller id: {0} vendor:{1} recivied msg: {2}",
Ctr.Id,
"Vendor1Class",
msg);
return true;
}
}
//Vendor2Proccessor.cs
public class Vendor2Proccessor : IControllerProccessor
{
public SimpleController Ctr { get; set; }
public bool sendMsg(string msg)
{
//specific to vendor code, for example calls to vendor1 SDK
Console.WriteLine("Controller id: {0} vendor:{1} recivied msg: {2}",
Ctr.Id,
"Vendor2Class",
msg);
return true;
}
}
//ControllerProccessor.cs
public class ControllerProccessor : IControllerProccessor
{
public SimpleController Ctr {get; set;}
private readonly IKernel kernel;
public ControllerProccessor(IKernel _kernel)
{
kernel = _kernel;
}
public bool sendMsg(string msg)
{
var param = new Ninject.Parameters.PropertyValue("Ctr", Ctr);
return kernel.Get<IControllerProccessor>(Ctr.Vendor, param).sendMsg(msg);
}
}
//HelloWorldService.cs
public class HelloWorldService : IHelloWorldService
{
private readonly IDbConnectionFactory dbFactory;
private readonly IControllerProccessor ctrProccessor;
public HelloWorldService(IDbConnectionFactory _dbFactory, IControllerProccessor _ctrProccesor)
{
dbFactory = _dbFactory;
ctrProccessor = _ctrProccesor;
}
public bool sendMsgToAllControllers(string msg)
{
var db = dbFactory.Open();
var controllers = db.Select<SimpleController>();
foreach(var ctr in controllers)
{
ctrProccessor.Ctr = ctr;
ctrProccessor.sendMsg(msg);
}
db.Close();
return true;
}
}
//SimpleController.cs
[DataContract]
[Alias("SimpleController")]
public class SimpleController
{
[AutoIncrement]
[DataMember]
public int? Id { get; set; }
[DataMember]
public string Vendor { get; set; }
}
When I call sendMsgToAllControllers("TEST_MESSAGE") console output:
Controller id: 2 vendor:Vendor1Class recivied msg: TEST MESSAGE
Controller id: 3 vendor:Vendor2Class recivied msg: TEST MESSAGE
Controller id: 4 vendor:Vendor2Class recivied msg: TEST MESSAGE
How I can refactor above implementation so that it was in DI style, and dont use IoC locator anti-pattern (or in my case this is not anti-pattern) ?
In future I will move implementations (vendor1, vendor2, etc..) in separate assembly and do runtime binding. (Here I want to plugin system)
I also would appreciate any suggestions to improve my code. Very thanks.
Modification of implementation
After thinking process I came to the following:
I remove ControllerProccessor class instead I create ControllerProcessorFactory:
public class ControllerProcessorFactory : IControllerProcessorFactory
{
private readonly IResolutionRoot resolutionRoot;
public ControllerProcessorFactory(IResolutionRoot _resolutionRoot)
{
resolutionRoot = _resolutionRoot;
}
public IControllerProcessor Create(SimpleController ctr)
{
IControllerProcessor processor = resolutionRoot.Get<IControllerProcessor>(ctr.Vendor);
processor.Ctr = ctr;
return processor;
}
}
In Bindings:
kernel.Bind<IControllerProcessorFactory>().To<ControllerProcessorFactory>();
kernel.Bind<IControllerProcessor>().To<Vendor1Processor>()
.Named("vendor1");
kernel.Bind<IControllerProcessor>().To<Vendor2Processor>()
.Named("vendor2");
Usage (wcf class):
public class HelloWorldService : IHelloWorldService
{
private readonly IDbConnectionFactory dbFactory;
private readonly IControllerProcessorFactory ctrProcessorFactory;
public HelloWorldService(IDbConnectionFactory _dbFactory, IControllerProcessorFactory _ctrProcFactory)
{
dbFactory = _dbFactory;
ctrProcessorFactory = _ctrProcFactory;
}
public bool sendMsgToAllControllers(string msg)
{
var db = dbFactory.Open();
var controllers = db.Select<SimpleController>();
foreach(var ctr in controllers)
{
var ctrProcessor = ctrProcessorFactory.Create(ctr);
ctrProcessor.sendMsg(msg);
}
db.Close();
return true;
}
}
kernel.Get<IControllerProccessor>(Ctr.Vendor, param) is service locator,
but then again that doesn't always mean "it" is a problem. If it's easily interchangable, then it's not a big deal (well at least that's the opinion of some). Easily interchangeable? Create a specific factory interface whose only responsibility is to return all the processors.
The implementation then would consist of exactly return kernel.Get<IControllerProccessor>(Ctr.Vendor, param);. As long as the implementation is part of the composition root this specfici dependency on ninject is ok.
Shorter Alternative
Now, to be honest, your design looks superfluosly complicated to me, but then again, i don't know all the details. So for now i'm just using the name parameter, but you can easily add parameters (almost) as you like, it'll still work:
Just inject a Func<string, IControllerProcessor> instead of the kernel:
public ControllerProccessor(
Func<string,IControllerProcessor>> controllerProcessorFactory)
You can then specfiy a binding as follows:
private static IControllerProcessor CreateSpecificControllerProcessor(
IResolutionRoot resolutionRoot, string vendorName)
{
return resolutionRoot.Get<IControllerProcessor>(vendorName);
}
Bind<Func<IControllerProcessor>()
.ToConstant(vendorName => CreateSpecficiControllerProcessor(this.Kernel, vendorName));
Instead of specifying the Binding for the Func it might be possible to use Ninject.Extensions.Factory. Note however, that when you use this extension it won't be possible to Bind any Func manually anymore (the binding will be overriden by the extensions generation mechanism).
Look at Dynamic module loading in their documentation.
i.e.
kernel.Load("*.dll");
But make sure you do this at startup so you don't overwhelm your system at runtime.
As far as your pattern, I would recommend using the GetAll() method on the kernel as that will give you more flexibility and control
IEnumerable<IControllerProccessor> processors = kernel.GetAll<IControllerProccessor>();
foreach(var processor in processors)
processor.sendMsg(....);
When registering a type for my unity container, I need to pass in the calling class's type into the constructor of the resolved object.
This is the class where I am injecting some interfaces into the constructor.
namespace MyNamespace
{
internal class ProcessingService: IProcessingService
{
private readonly ISomeClass1 someClass1;
private readonly ISomeClass2 someClass2;
public ProcessingService(ISomeClass1 someClass1, ISomeClass2 someClass2)
{
this.someClass1 = someClass1;
this.someClass2 = someClass2;
}
}
}
SomeClass2 expects Type in the constructor:
public class SomeClass2
{
public SomeClass2(Type type)
{
//...
}
}
Here is my unity bootstrap class where I set up my container. Now, for ISomeClass2, when it resolves to SomeClass2, it needs to pass in the type of ProcessingService.
namespace MyNamespace
{
public class UnityBootstrap : IUnityBootstrap
{
public IUnityContainer Configure(IUnityContainer container)
{
return container
.RegisterType<ISomeClass1, SomeClass1>()
.RegisterType<ISomeClass2>(new InjectionFactory(fac =>
{
// IMethodBase.GetCurrentMethod().DeclaringType is returning MyNamespace.UnityBootstrap
// whereas I need to get MyNamespace.ProcessingService
return new SomeClass2(MethodBase.GetCurrentMethod().DeclaringType);
}));
}
}
}
Is there a way to do this using the InjectionFactory (or some other way within my Configure method)?
If you have control over the ProcessingService, you could create a generic wrapper around SomeClass2 and then register it using open generics. But that would require you modify the constructor of the ProcessingService.
public interface IGenericSomeClass2<T>: ISomeClass2 {}
public class GenericSomeClass2<T>: IGenericSomeClass2<T>
{
private readonly ISomeClass2 someClass2;
public GenericSomeClass2()
{
this.someClass2 = new SomeClass2(typeof(T));
}
// Pass-through implementation
}
public IUnityContainer Configure(IUnityContainer container)
{
return container
.RegisterType<ISomeClass1, SomeClass1>()
.RegisterType(typeof(IGenericSomeClass2<>), typeof(GenericSomeClass2<>));
}
internal class ProcessingService: IProcessingService
{
private readonly ISomeClass1 someClass1;
private readonly ISomeClass2 someClass2;
public ProcessingService(ISomeClass1 someClass1, IGenericSomeClass2<ProcessingService> someClass2)
{
this.someClass1 = someClass1;
this.someClass2 = someClass2;
}
}
IMHO, there are two points of view to this problem:
1) If SomeClass2 will always use the type ProcessingService then you can pass the type argument directly into the InjectionFactory
container.RegisterType<ISomeClass2>(new InjectionFactory(_ =>
{
return new SomeClass2(typeof(ProcessingService));
}));
2) Otherwise, if the type argument differs throughout application you should consider adding a registration method to interface ISomeClass2 and register the type from within the constructor to emphasize the dependency/variation.
public interface ISomeClass2
{
void DoSomething();
void RegisterProcessingServiceType(Type processingServiceType);
}
public class SomeClass2 : ISomeClass2
{
private Type _type;
public void DoSomething()
{
if(_type == null)
throw InvalidOperationException("Register processing service type before doing stuff.");
// actually do something
}
public void RegisterProcessingServiceType(Type serviceType)
{
_type = serviceType;
}
}
internal class ProcessingService: IProcessingService
{
private readonly ISomeClass1 someClass1;
private readonly ISomeClass2 someClass2;
public ProcessingService(ISomeClass1 someClass1, ISomeClass2 someClass2)
{
this.someClass1 = someClass1;
this.someClass2 = someClass2;
this.someClass2.RegisterProcessingServiceType(this.GetType());
}
}
If you do not control ProcessingService (or other consumers of SomeClass2), you could customize the registration of those consumers. This method is a bit more intrusive because you would have to create an injection factory for every consumer.
container
.RegisterType<IProcessingService, ProcessingService>(new InjectionFactory((c, type, name) =>
{
return new ProcessingService(c.Resolve<ISomeClass1>(), new SomeClass2(type));
}));
In the following example, I want to test the TestMe.DoSomething() function.
I want to mock the ISomething interface that is used within this method and make it return different values (depending on the specific unit test.)
In real life the ISomething interface winds up calling out to expensive 3rd party resources -- I definitely don't want to just call a real ISomething.
Here is the example structure:
class TestMe
{
public void DoSomething()
{
ISomething s = SomethingFactory();
int i = s.Run();
//do things with i that I want to test
}
private ISomething SomethingFactory()
{
return new Something();
}
}
interface ISomething
{
int Run();
}
class Something : ISomething
{
public int Run()
{
return 1;
}
}
Here is code that doesn't work:
var fakeSomething = new Mock<ISomething>();
var testMe = new TestMe();
Mock.Get(testMe).Setup(p => p.SomethingFactory()).Returns(fakeSomething.Object);
testMe.DoSomething();
Because SomethingFactory() is private, I cannot set the return value from that method to be what I want.
Any advice on how I can solve this?
Make the factory a full interface / class and remove the SomethingFactory method from TestMe.
public interface ISomethingFactory {
ISomething MakeSomething();
}
public sealed class SomethingFactory {
public ISomething MakeSomething() {
return new Something();
}
}
class TestMe
{
private readonly ISomethingFactory _somethingFactory;
public TestMe(ISomethingFactory somethingFactory) {
_somethingFactory = somethingFactory;
}
public void DoSomething()
{
ISomething s = _somethingFactory.MakeSomething();
int i = s.Run();
//do things with i that I want to test
}
}
This will allow you to mock ISomethingFactory to return a mock of ISomething.
While I think you may protest this solution as too drastic a change, I think its better than making a class that's not sealed with a members who's only reason for being virtual is for testing.
You can inject your dependency. If you don't want to break all your callers you can add two constructors and use the one that lets you inject fake in tests
class TestMe
{
private readonly ISomething something;
TestMe() : this(new RealSomething()
{
}
TestMe(ISomething sth)
{
something = sth;
}
public void DoSomething()
{
ISomething s = SomethingFactory();
int i = s.Run();
//do things with i that I want to test
}
private ISomething SomethingFactory()
{
return new Something();
}
}
Second way would be to change the
SomethingFactory
method to protected virtual and override it in derived class and use that class instead, or to setup
class TestableTestMe : TestMe
{
private readonly ISomething something;
TestableTestMe(ISomething testSpecific)
{
something = testSpecific;
}
public void DoSomething()
{
ISomething s = SomethingFactory();
int i = s.Run();
//do things with i that I want to test
}
protected override ISomething SomethingFactory()
{
return something;
}
}
This technique is called "extract and override"
Changing SomethingFactory() to be protected virtual allows you to use Moq.Protected to access the method by its name:
public class TestMe
{
public void DoSomething()
{
ISomething s = SomethingFactory();
int i = s.Run();
//do things with i that I want to test
}
protected virtual ISomething SomethingFactory()
{
return new Something();
}
}
public interface ISomething
{
int Run();
}
public class Something : ISomething
{
public int Run()
{
return 1;
}
}
So you can run this test:
var fakeSomething = new Mock<ISomething>();
fakeSomething.Setup(p => p.Run()).Returns(2);
var testMe = new Mock<TestMe>();
testMe.Protected().Setup<ISomething>("SomethingFactory").Returns(fakeSomething.Object);
testMe.Object.DoSomething();