Ninject and Activator.CreateInstance - Missing Method exceptions - ninject

So, I've created a class that finds all classes in my project that implement a certain interface, generates instances of those classes then aggregates the results of a method provided from the contract of that interface.
Here is my code
public string Parse(string src,JToken json)
{
var type = typeof(IReplaceTokens);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(t => type.IsAssignableFrom(t) && t.IsClass);
return types.Select(tokenReplacer => Activator.CreateInstance(tokenReplacer) as IReplaceTokens)
.Aggregate(src, (current, tokenReplacerInstance) => tokenReplacerInstance.ReplaceTokens(current, json));
}
I'm getting MissingMethod exception methods from activator because it can't find a paramaterless constructor but the two parameters required by the constructors of these types should be injected by Ninject as they are bound.
From my NinjectModule
Bind<IConfigReader>().To<JsonConfigReader>()
.InSingletonScope()
.WithConstructorArgument("appId", _appId)
.WithConstructorArgument("type", _type);
var configReader = this.KernelInstance.GetService(typeof (IConfigReader)) as IConfigReader;
if (configReader == null || configReader.JsonWrappedInExercise) { Bind<IJsonExtractor>().To<Pm3JsonExtractor>().InSingletonScope(); }
else { Bind<IJsonExtractor>().To<NakedJsonExtractor>().InSingletonScope(); }
Signatures for all the Constructors Activator should be constructing
public MonthTokenReplacer(IJsonExtractor extractor, IConfigReader reader)
public DateTokenReplacer(IJsonExtractor extractor, IConfigReader reader)
public LastNameTokenReplacer(IJsonExtractor extractor, IConfigReader reader) : base(extractor, "[[LastName]]", reader.FirstNameField) { }
public TokenReplacerBase(IJsonExtractor extractor, string token,string objectKey)
Plus two others with parameterless constructors.
Any idea why this isn't working?

By calling Activator.CreateInstance you by pass Ninject like you do when using the new operator. You are responsible to provide any dependency yourself.
call kernel.Get(tokernReplacer) instead.

Related

In ASP.NET core, inject a service with constructor parameters [duplicate]

Having the following service constructor
public class Service : IService
{
public Service(IOtherService service1, IAnotherOne service2, string arg)
{
}
}
What are the choices of passing the parameters using .NET Core IOC mechanism
services.AddSingleton<IOtherService , OtherService>();
services.AddSingleton<IAnotherOne , AnotherOne>();
services.AddSingleton<IService>(x =>
new Service(
services.BuildServiceProvider().GetService<IOtherService>(),
services.BuildServiceProvider().GetService<IAnotherOne >(),
""));
Is there any other way ?
The expression parameter (x in this case) of the factory delegate is an IServiceProvider.
Use that to resolve the dependencies:
_serviceCollection.AddSingleton<IService>(x =>
new Service(x.GetRequiredService<IOtherService>(),
x.GetRequiredService<IAnotherOne>(),
""));
The factory delegate is a delayed invocation. Whenever the type is to be resolved, it will pass the completed provider as the delegate parameter.
The recommended way to achieve this is to use the Options pattern - note that this applies to any .NET Core/5 application, not just ASP.NET Core. But there are use cases where it's impractical (e.g. when parameters are only known at runtime, not at startup/compile-time) or you need to dynamically replace a dependency.
It's very useful when you need to replace a single dependency (be it a string, integer or another type of dependency) or when using a 3rd-party library which accepts only string/integer parameters and you require runtime parameters.
You could try ActivatorUtilities.CreateInstance<T>(IServiceProvider, Object[]) as a shortcut rather than resolving every single dependency manually:
_serviceCollection.AddSingleton<IService>(x =>
ActivatorUtilities.CreateInstance<Service>(x, "");
);
The parameters to pass to your service's constructor (the object[] parameter to CreateInstance<T>/CreateInstance) allows you to specify parameters that should be injected directly, as opposed to resolved from the service provider. They are applied from left to right as they appear (i.e. first string will be replaced with the first string-typed parameter of the type to be instantiated).
ActivatorUtilities.CreateInstance<Service> is used in many places to resolve service and replace one of the default registrations for this single activation.
For example, if you have a class named MyService, and it has IOtherService, ILogger<MyService> as dependencies and you want to resolve the service but replace the default service of IOtherService (say it's OtherServiceA) with OtherServiceB, you could do something like:
myService = ActivatorUtilities.CreateInstance<Service>(serviceProvider,
new OtherServiceB());
Then the first parameter of IOtherService will get OtherServiceB injected, rather than OtherServiceA - but the remaining parameters will come from the service provider.
This is helpful when you have many dependencies and want just to treat a single one specially (i.e. replace a database-specific provider with a value configured during the request or for a specific user, something you only know at runtime and/or during a request - not when the application is built/started).
If performance is a concern, you can use ActivatorUtilities.CreateFactory(Type, Type[]) to create a factory method instead. GitHub reference and benchmark.
This is useful when the type is resolved very frequently (such as in SignalR and other high request scenarios). Basically, you'd create an ObjectFactory via
var myServiceFactory = ActivatorUtilities.CreateFactory(typeof(MyService), new Type[] { typeof(IOtherService), });
then cache it (as a variable etc.) and invoke it where needed:
MyService myService = myServiceFactory(serviceProvider, myServiceOrParameterTypeToReplace);
This all works perfectly with primitive types too - here's an example I tested with:
class Program
{
static void Main(string[] args)
{
var services = new ServiceCollection();
services.AddTransient<HelloWorldService>();
services.AddTransient(p => p.ResolveWith<DemoService>("Tseng", "Stackoverflow"));
var provider = services.BuildServiceProvider();
var demoService = provider.GetRequiredService<DemoService>();
Console.WriteLine($"Output: {demoService.HelloWorld()}");
Console.ReadKey();
}
}
public class DemoService
{
private readonly HelloWorldService helloWorldService;
private readonly string firstname;
private readonly string lastname;
public DemoService(HelloWorldService helloWorldService, string firstname, string lastname)
{
this.helloWorldService = helloWorldService ?? throw new ArgumentNullException(nameof(helloWorldService));
this.firstname = firstname ?? throw new ArgumentNullException(nameof(firstname));
this.lastname = lastname ?? throw new ArgumentNullException(nameof(lastname));
}
public string HelloWorld()
{
return this.helloWorldService.Hello(firstname, lastname);
}
}
public class HelloWorldService
{
public string Hello(string name) => $"Hello {name}";
public string Hello(string firstname, string lastname) => $"Hello {firstname} {lastname}";
}
// Just a helper method to shorten code registration code
static class ServiceProviderExtensions
{
public static T ResolveWith<T>(this IServiceProvider provider, params object[] parameters) where T : class =>
ActivatorUtilities.CreateInstance<T>(provider, parameters);
}
Prints
Output: Hello Tseng Stackoverflow
If you feel uncomfortable with newing the service, you could use the Parameter Object pattern.
So extract the string parameter into its own type
public class ServiceArgs
{
public string Arg1 {get; set;}
}
And the constructor will now look like
public Service(IOtherService service1,
IAnotherOne service2,
ServiceArgs args)
{
}
And the setup
_serviceCollection.AddSingleton<ServiceArgs>(_ => new ServiceArgs { Arg1 = ""; });
_serviceCollection.AddSingleton<IOtherService , OtherService>();
_serviceCollection.AddSingleton<IAnotherOne , AnotherOne>();
_serviceCollection.AddSingleton<IService, Service>();
The first benefit is if you need to change the Service constructor and add new services to it, then you don't have to change the new Service(... calls. Another benefit is the setup is a bit cleaner.
For a constructor with a single parameter or two, this might be too much though.
You can inject dependencies with this process also
_serviceCollection.AddSingleton<IOtherService , OtherService>();
_serviceCollection.AddSingleton<IAnotherOne , AnotherOne>();
_serviceCollection.AddSingleton<IService>(x=>new Service( x.GetService<IOtherService>(), x.GetService<IAnotherOne >(), "" ));

Make two factories return the same object that implements both interfaces

(I use C# in my examples, but this question is not specifically about C#.)
We have factories to create objects for multiple interfaces, one factory per interface.
Say we have a PrintingFactory to create an object implementing IPrinting and a ScanningFactory for IScanning. We have concrete printers implementing IPrinting and concrete scanners implementing IScanning and the factories decide which implementation is chosen.
In ScanningFactory I have:
public static IScanning Build()
{
...
return new CanonXYZ2000();
}
I have similar code in PrintingFactory, and in main I have:
scanner = ScanningFactory.Build();
printer = PrintingFactory.Build();
Now, what happens if I want to instantiate one object that implements both interfaces?
public class CanonXYZ2001MultiPurpose: IPrinting, IScanning {...}
I would like both factories to return the same object. How do I do this properly?
If i understand you correctly you are asking if CanonXYZ2001MultiPurpose can be created by both ScanningFactory and PrintingFactory ?
In this case both factories can return instances of CanonXYZ2001MultiPurpose with no issues, since this class implements both interfaces:
Scanning factory code:
public static IScanning Build()
{
...
return new CanonXYZ2001MultiPurpose ();
}
Printing factory code:
public static IPrinting Build()
{
...
return new CanonXYZ2001MultiPurpose ();
}
Both variables now hold instance of CanonXYZ2001MultiPurpose:
var scanner = ScanningFactory.Build();
var printer = PrintingFactory.Build();

NSubstitute throws CouldNotSetReturnDueToTypeMismatchException when mocking Query on NHibernate Session

I have a repository offering a GetAll method which again calls the Query extension method on the ISession instance of NHibernate.
public ICollection<Product> GetAll()
{
return _session.Query<Product>().ToList();
}
My unit test looks like this:
[Test]
public void GetAllReturnsCollectionFromSession()
{
IQueryable<Product> productList = new ProductListBuilder().Build().AsQueryable();
_fixture.Session.Query<Product>().Returns(productList);
var sut = _fixture.CreateSut();
var result = sut.GetAll();
Assert.AreSame(productList, result);
_fixture.Session.Received().Query<Product>();
}
In the _fixture.Session.Query().Returns(productList) statement, NSubstitute throws the following exception:
NSubstitute.Exceptions.CouldNotSetReturnDueToTypeMismatchException : Can not return value of type IQueryable`1Proxy for ISession.GetSessionImplementation (expected type ISessionImplementor).
Make sure you called Returns() after calling your substitute (for example: mySub.SomeMethod().Returns(value)),
and that you are not configuring other substitutes within Returns() (for example, avoid this: mySub.SomeMethod().Returns(ConfigOtherSub())).
If you substituted for a class rather than an interface, check that the call to your substitute was on a virtual/abstract member.
Return values cannot be configured for non-virtual/non-abstract members.
Correct use:
mySub.SomeMethod().Returns(returnValue);
Potentially problematic use:
mySub.SomeMethod().Returns(ConfigOtherSub());
Instead try:
var returnValue = ConfigOtherSub();
mySub.SomeMethod().Returns(returnValue);
at NSubstitute.Core.ConfigureCall.CheckResultIsCompatibleWithCall(IReturn valueToReturn, ICallSpecification spec)
at NSubstitute.Core.ConfigureCall.SetResultForLastCall(IReturn valueToReturn, MatchArgs matchArgs)
at NSubstitute.Core.CallRouter.LastCallShouldReturn(IReturn returnValue, MatchArgs matchArgs)
at NSubstitute.Core.SubstitutionContext.LastCallShouldReturn(IReturn value, MatchArgs matchArgs)
at NSubstitute.SubstituteExtensions.Returns[T](MatchArgs matchArgs, T returnThis, T[] returnThese)
at NSubstitute.SubstituteExtensions.ReturnsForAnyArgs[T](T value, T returnThis, T[] returnThese)
at Statoil.Wellcom.DataLayer.Implementation.Oracle.UnitTests.Repositories.DwapplicationRepositoryTests.GetAllReturnsCollectionFromSession() in C:\git\WELLCOM\source\Statoil.Wellcom.DataLayer.Implementation.Oracle.UnitTests\Repositories\DwapplicationRepositoryTests.cs:line 123
It looks like NSubstitute is unable to set the return value due to Query being an extension method. How would I go about mocking the extension method call on the ISession?
The easiest solution is to wrap your ISession in another interface/concrete class so you can stub that out:
public interface ISessionWrapper
{
IQueryable<T> Query<T>();
}
public class SessionWrapper : ISessionWrapper
{
private readonly ISession _session;
public SessionWrapper(ISession session)
{
_session = session;
}
public IQueryable<T> Query<T>()
{
return _session.Query<T>();
}
}
There is no way to mock extension method with NSubstitute, however if you know what extension method is using inside, than you can mock that. Your test will use extension method on mocked object and eventually it will use mocked method. Difficult part is to know what is going on inside.
It worked for me in projects, where I knew all the source code and I could check what's inside.

Serialize class based on one interface it implements with Jackson or Gson

I have the following:
An interface I1 extends Ia, Ib, Ic
An interface I2.
A class C implements I1, I2. And this class has its own setters and getters as well.
C cInstance = new C():
//Jackson
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(new File("somefile.json"), cInstance);
//Gson
Gson gson = new Gson();
String json = gson.toJson(cInstance);
The output will be cInstance serialized according to the properties of C and what it inherited.
However, I like the properties are being serialized to be according to the setters/getters in I1 (only the cInstance properties represented in the I1 interface).
How can I do this with Jackson knowing that I have too many classes with the same problem and I can't modify the class definition or add annotations.
And the same issue applies to Deserialization (Deserializing according to an interface)
Thanks
First of all, you can always attach "mix-in annotations" even without adding annotations directly (see wiki page). With this, annotation to use would be:
#JsonSerialize(as=MyInterface.class)
but if you do not want to use mix-ins, you can force specific type to use with
objectMapper.typedWriter(MyInterface.class).writeValue(....)
Jackson's VisibilityChecker provides an easy way for filtering certain properties, especially because it allows you to test for visibility (equals "will be serialized or not") for each method/field individually.
At least this helps for the serialization phase.
Here is what I did (using Jackson version 1.9.11):
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.introspect.AnnotatedMethod;
import org.codehaus.jackson.map.introspect.VisibilityChecker;
public static class InterfaceVisibilityChecker extends VisibilityChecker.Std {
private final Set<Method> visibleMethods;
public InterfaceVisibilityChecker(Class<?>... clazzes) {
super(JsonAutoDetect.Visibility.PUBLIC_ONLY);
this.visibleMethods = new HashSet<>();
for (Class<?> clz : clazzes) {
this.visibleMethods.addAll(Arrays.asList(clz.getMethods()));
}
}
#Override
public boolean isGetterVisible(Method m) {
return super.isGetterVisible(m) && isVisible(m);
}
#Override
public boolean isGetterVisible(AnnotatedMethod m) {
return isGetterVisible(m.getAnnotated());
}
private boolean isVisible(Method m) {
for (Method visiMthd : visibleMethods) {
if (isOverwriteMethod(m, visiMthd)) return true;
}
return false;
}
private boolean isOverwriteMethod(Method subMethod, Method superMethod) {
// names must be equal
if (! subMethod.getName().equals(superMethod.getName())) return false;
// return types must be assignable
if (! superMethod.getReturnType().isAssignableFrom(subMethod.getReturnType())) return false;
// parameters must be equal
if (! Arrays.equals(subMethod.getParameterTypes(), superMethod.getGenericParameterTypes())) return false;
// classes must be assignable
return superMethod.getDeclaringClass().isAssignableFrom(subMethod.getDeclaringClass());
}
}
The main idea is to use the standard VisibilityChecker and extend it by a check whether the method is declared in one of the given interfaces.
The checker is applied to an ObjectMapper instance using the following snippet:
ObjectMapper om = new ObjectMapper();
om.setVisibilityChecker(new InterfaceVisibilityChecker(
I1.class,
I2.class,
Ia.class,
Ib.class,
Ic.class
));
Some comments on the solution above:
The checker is not complete, methods like isIsGetterVisible or isFieldVisible can be handled in a similar manner if needed.
isOverwriteMethod is not optimized at all, it's checks could be cached.

PexChoose non generic methods

Is there any way to specify the return type for PexChoose at runtime? For example PexChoose.Value(name, Type)?
This would be useful to make general models that generate values of different types depending on runtime contraints.
You could build your own helper class which will call the generic version via reflection.
For instance, to create a non-generic version of PexChoose.Value(string name)
public static class MyPexChoose
{
public static object Value(Type myType, string name)
{
// Find the PexChoose.Value() method which has a single string parameter
MethodInfo method = typeof(PexChoose).GetMethod("Value", new Type[1] {typeof(string)});
// Make and invoke the generic version of it
MethodInfo generic = method.MakeGenericMethod(myType);
return generic.Invoke(typeof(PexChoose), new object[1] { name });
}
}
Then the call
MyPexChoose(typeof(DateTime), "MyChosen");
is equivalent to
PexChoose<DateTime>("MyChosen");