Instantiate DbContext-derived class with Mehdime.Entity AmbientDbContextLocator - ef-code-first

can anyone tell me what I am doing wrong?
I am wanting to use Mehdime.Entity from https://www.nuget.org/packages/Mehdime.Entity in order to manage my DBContext-derived classes in a Console Application. I am also using NInject.
The connection strings for my DBContext-derived classes are partially generated from standard app.config ConnectionStrings and also by an AppDomain value that (in my Console App case) comes in via a command line argument.
My DBContext-derived classes have their connection strings prepared using a program-implemented class which takes into account of the command line argument as follows:
public class TaskManagementDbContext : DbContext
{
public TaskManagementDbContext(IConnectionStringResolver csr) :
base(csr.GetConnectionString("Default"))
{
}
}
(IConnectionStringResolver basically implements GetConnectionString() which returns the connection string by using given named standard app.config ConnectionString and the command line argument.
This is fine when I use NInject to instantiate the DbContext directly but when trying to use with Mehdime.Entity, it is AmbientDbContextLocator that is doing the instantiation and it throws a MissingMethodException because it requires my DBContext-derived class to have a parameterless constructor:
public class TaskRepository : ITaskRepository
{
private readonly IAmbientDbContextLocator _ambientDbContextLocator;
private TaskManagementDbContext DbContext
{
get
{
// MissingMethodException thrown "No parameterless constructor defined for this object"
var dbContext = _ambientDbContextLocator.Get<TaskManagementDbContext>();
...
}
}
How should I provide a connection string to my DBContext-derived classes at run-time in this situation? I suspect I am going about this the wrong way. Thanks.

OK. I've worked out the solution and I'm putting it here for anyone else with this issue:
Create your own implementation of IDbContextFactory (see below). I put this in the same class library as my Data Access Layer (i.e. my DbContexts). You will see in my example how I "look for" a specific constructor prototype (in my case, 1 parameter of type IDbContextFactory - your's will no doubt be different). If found, get the actual parameters and invoke a new instance of your DBContext-derived class. If not found, you can throw an exception or in my case, try to call the default constructor (if exists).
Code:
using System;
using System.Data.Entity;
using Mehdime.Entity;
using Ninject;
using TaskProcessor.Common;
namespace TaskProcessor.Data.Connection
{
public class DbContextWithCSRFactory : IDbContextFactory
{
public TDbContext CreateDbContext<TDbContext>() where TDbContext : DbContext
{
// Try to locate a constuctor with a single IConnectionStringResolver parameter...
var ci = typeof(TDbContext).GetConstructor(new[] { typeof(IConnectionStringResolver) });
if(ci != null)
{
// Call it with the actual parameter
var param1 = GlobalKernel.Instance.Get<IConnectionStringResolver>();
return (TDbContext)ci.Invoke(new object[] { param1 });
}
// Call parameterless constuctor instead (this is the default of what DbContextScope does)
return (TDbContext)Activator.CreateInstance<TDbContext>();
}
}
}
Create a binding in NInject so that your IDbContextFactory implementation is called:
Code:
private void AddBindings(IKernel kernel)
{ ...
kernel.Bind<IDbContextFactory>().To<Data.Connection.DbContextWithCSRFactory>().InSingletonScope();
}
Everything now falls into place.

Related

How to decorate objects created by a custom factory using .NET Core DI?

Given I have a factory class responsible for constructing instances of a certain service that has constructor parameters that can only be resolved at runtime, is there a way to leverage container-driven decoration?
Consider the following class which relies on a parameter that is only defined at runtime:
interface IFooService
{
void DoServicyStuff();
}
class MyFooService : IFooService
{
public MyFooService(string somePeskyRuntimeArgument)
{
this.peskyValue = somePeskyRuntimeArgument;
}
public void DoServicyStuff()
{
// do some stuff here with the peskyValue...
}
}
Since the value can only be provided at runtime, we need to move away from the constructor injection and into a method-level parameter passing. This is commonly achieved using a factory implementation like this:
interface IFooServiceFactory
{
IFooService CreateService(string heyItsNowAMethodLevelPeskyParameter);
}
class FooServiceFactory : IFooServiceFactory
{
public IFooService CreateService(string heyItsNowAMethodLevelPeskyParameter)
{
return new MyFooService(heyItsNowAMethodLevelPeskyParameter);
}
}
While this works fine if the intent is to just abstract away the construction of the service, it poses a challenge to decorate the IFooService instance.
For scenarios where no runtime parameter is involved, this can be easily achieved by tapping into the container to provide our service for us. The example below uses the Scrutor library to decorate the interface with a logging decorator implementation:
class FooServiceFactory : IFooServiceFactory
{
private readonly IServiceProvider serviceProvider;
public FooServiceFactory(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider
}
public IFooService CreateService(string heyItsNowAMethodLevelPeskyParameter)
{
return this.serviceProvider.GetRequiredInstance<IFooService>();
}
}
...
services
.AddTransient<IFooService, MyFooService>()
.AddTransient<IFooServiceFactory, FooServiceFactory>()
.Decorate<IFooService, LoggingFooService>();
But since MyFooService takes a primitive value as an argument, we cannot rely on GetRequiredService<T> to obtain the instance, as it will fail to find "a registration for string" when building the concrete class.
Similarly, changing the factory to rely on ActivatorUtilities's .CreateInstance or .CreateFactory methods will end up creating the objects while completely ignoring the container registrations, thus leaving us without any decorator.
I know I have at least 2 options to decorate the objects manually, namely:
Using the factory itself to manually create the decorator:
public IFooService CreateService(string heyItsNowAMethodLevelPeskyParameter)
{
return new LoggingService(
new MyFooService(heyItsNowAMethodLevelPeskyParameter));
}
Using a factory decorator to inject a decorator after the instance is created:
abstract class FooServiceFactoryDecorator : IFooServiceFactory
{
private readonly IFooServiceFactory fooServiceFactory;
protected FooServiceFactory(IFooServiceFactory fooServiceFactory)
{
this.fooServiceFactory = fooServiceFactory;
}
public virtual IFooService CreateService(string heyItsNowAMethodLevelPeskyParameter)
{
return this.fooServiceFactory.CreateService(heyItsNowAMethodLevelPeskyParameter);
}
}
class LoggingFooServiceFactory : FooServiceFactoryDecorator
{
private readonly IFooServiceFactory fooServiceFactory;
public FooServiceFactory(IFooServiceFactory fooServiceFactory)
{
this.fooServiceFactory = fooServiceFactory;
}
public override IFooService CreateService(string heyItsNowAMethodLevelPeskyParameter)
{
return new LoggingFooService(
this.fooServiceFactory.CreateService(heyItsNowAMethodLevelPeskyParameter));
}
}
...
services
.AddTransient<IFooServiceFactory, FooServiceFactory>()
.Decorate<IFooServiceFactory, LoggingFooServiceFactory>()
Neither of these allows me to directly use .Decorate on top of the service interface. The first option works but is heavily coupled (meaning I'd have to keep changing it if I want to add other decorators into the mix), while the second version is less coupled, but still forces me to writing one factory decorator per service decorator and thus leads into a much more complex solution.
Another pain point is dependencies on the decorators themselves (for example, ILogger<T> on the LoggingFooService), which I could potentially solve by leveraging ActivatorUtilities to create the decorators instead of newing them up manually.
I could also potentially generalize the "factory decorator" so that the decoration function is parameterized and thus the class can be reused, but it is still very convoluted and hard to maintain, while also not providing as good a syntax for consumers to add new decorators.
class DecoratedFooServiceFactory<TDecorator> : FooServiceFactoryDecorator
where TDecorator : IFooService
{
private readonly IFooServiceFactory fooServiceFactory;
private readonly IServiceProvider serviceProvider;
public FooServiceFactory(
IFooServiceFactory fooServiceFactory,
IServiceProvider serviceProvider)
{
this.fooServiceFactory = fooServiceFactory;
this.serviceProvider = serviceProvider;
}
public override IFooService CreateService(string heyItsNowAMethodLevelPeskyParameter)
{
return ActivatorUtilities.CreateInstance<TDecorator>(
this.serviceProvider,
this.fooServiceFactory.CreateService(heyItsNowAMethodLevelPeskyParameter));
}
}
...
services
.AddTransient<IFooServiceFactory, FooServiceFactory>()
.Decorate<IFooServiceFactory, DecoratedFooServiceFactory<LoggingFooService>>()
And finally, if I ever want to move away from using a factory and want to change to using the service directly, this will cause a significant setup change where I'd then have to configure all the decorators again in the container directly instead of just removing the factory registration as one normally would do.
How can I use a factory like this, while still keeping the capability of configuring decorators at the container level using the simple Scrutor syntax?
Ok, a couple of disclaimers first:
I agree with Steven here in that this looks like an anti-pattern and you will probably be better off redesigning your code to not require run-time values on service construction.
I additionally want to caution against using scrutor-like Decorate. While much less confident in this than in the first point, I believe hiding logging in decorators is much less convenient in the long run than it seems at first. Or at least that's what I saw after about a year of trying them out.
That said, let's see what can be done.
First, let's put some constraints on where the value is coming from. Specifically, let's say we can have a service providing that value, that looks like this:
public interface IValueProvider
{
string Get();
}
This actually allows us to have quite a bit of range. Implementation of that interface can:
Get value from external API - once or periodically in the background. It can even call it every time Get is called, but this is a very bad idea, as it will make construction asynchronous.
Get value that is stored in memory and allow some other service to update it. Say, expose a 'configuration' endpoint where a user can set a new value every once in a while.
Calculate the value based on some algorithm of your choice.
Once you have this service, you can register it like this:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IValueProvider, AwesomeValueProvider>();
services.AddSingleton<IFooServiceFactory, FooServiceFactory>();
services.AddTransient<IFooService>(sp =>
{
var factory = sp.GetRequiredService<IFooServiceFactory>();
var valueProvider = sp.GetRequiredService<IValueProvider>();
return factory.Create(valueProvider.Get());
});
}
Hope this helps

Mock logger giving me error for ASP.NET Core

I was trying to verify whether my log warning message is written via NUnit mocking. I am getting this error message :
An exception of type 'System.NotSupportedException' occurred in Moq.dll but was not handled in user code
Additional information: Invalid verify on a non-virtual (overridable in VB) member: m => m.LogWarning(String.Format("comments not found for part number :{0}", (Object)0), new[] { "111" })
code:
mockLogger.Verify(m => m.LogWarning($"comments not found for part number :{0}", "111"), Times.Exactly(1));
This is happening because NUnit mocking framework does not support extension methods. A few people on stack overflow have suggested to use Log method instead of level wise methods.
What am I missing?
Firstly, you don't need the $ at the start of the string. That's for string interpolation. The LogWarning message is doing a string.format, hence the {0}
Mock frameworks cannot directly mock static methods. The problem in your case is the LogWarning method - that is the static (extension) method.
The simplest way of overcoming this issue is by using a wrapper class. Here's how I got it, in your case.
Firstly I created an interface
public interface IMyLogWarning
{
void LogWarning(string msg, params object[] args);
}
Then I created a class which implements that interface
public class MyLogWarning<T> : IMyLogWarning where T : class
{
private readonly ILogger _logger;
public MyLogWarning(ILogger<T> logger)
{
// Using constructor for DI
_logger = logger;
}
public void LogWarning(string msg, params object[] args)
{
_logger.LogWarning(msg, args);
}
}
The reason for these two is that I'll use these in my code as well as the unit test.
The constructor in the class is setup so it can be populated using dependency injection, something like this in your ConfigureServices method. Feel free to change this; was a quick stab at it on my part.
services.AddTransient<IMyLogWarning, MyLogWarning<MyViewModel>>();
You can then create a unit test that's roughly like this
[Test]
public void LoggingTest_LogAMessage_ConfirmedLogWasRun()
{
// TODO - add the rest of your test code
// Arrange
var warningMsg = "comments not found for part number :{0}";
var partNumber = "111";
var mockLogger = new Mock<IMyLogWarning>();
// Act
mockLogger.Object.LogWarning(warningMsg, partNumber);
// Assert
mockLogger.Verify(m => m.LogWarning(warningMsg, partNumber), Times.Exactly(1));
}

Pass object between two Around functions - AOP

I am doing Auditing for my Controller, Service and Dao layer. I have three Around aspect functions for Controller, Service and Dao respectively. I use a custom annotation which if present on the Controller method will invoke an Around aspect function. Inside the annotation I set a property which I wish to pass from the Controller Around function to the Service around function inside the Aspect class.
public #interface Audit{
String getType();
}
I will set the value of this getType from an interface.
#Around("execution(* com.abc.controller..*.*(..)) && #annotation(audit)")
public Object controllerAround(ProceedingJoinPoint pjp, Audit audit){
//read value from getType property of Audit annotation and pass it to service around function
}
#Around("execution(* com.abc.service..*.*(..))")
public Object serviceAround(ProceedingJoinPoint pjp){
// receive the getType property from Audit annotation and execute business logic
}
How can I pass an object between two Around functions?
Aspects are, by default, singleton objects. However, there are different instantiation models, which could be useful in use cases like yours. Using a percflow(pointcut) instantiation model, you could store the value of the annotation in your controller around advice and retrieve it in your service around advice. The following is just an example on how it would look like:
#Aspect("percflow(controllerPointcut())")
public class Aspect39653654 {
private Audit currentAuditValue;
#Pointcut("execution(* com.abc.controller..*.*(..))")
private void controllerPointcut() {}
#Around("controllerPointcut() && #annotation(audit)")
public Object controllerAround(ProceedingJoinPoint pjp, Audit audit) throws Throwable {
Audit previousAuditValue = this.currentAuditValue;
this.currentAuditValue = audit;
try {
return pjp.proceed();
} finally {
this.currentAuditValue = previousAuditValue;
}
}
#Around("execution(* com.abc.service..*.*(..))")
public Object serviceAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("current audit value=" + currentAuditValue);
return pjp.proceed();
}
}

Fail in calling Enable-Migrations for a generic DbContext class

Let's assume that I have this Entity Framework (v6.0) DbContext-based class, sitting in the "Food.Common" assembly:
public class FoodContext<T> : DbContext where T : Food<T>
{
public FoodContext() : base("MyConnectionString")
{
}
public DbSet<T> FoodElements { get; set; }
}
The above Food generic class is also sitting in the "Food.Common" assembly, and it is defined as:
public class Food<T> where T : Food<T>
{
// some code here...
public virtual T Copy()
{
// object copy goes here...
}
}
Also, I have this class which inherits from Food<T> and sits on the "Food.Extras" assembly:
public class HealthyFood : Food<HealthyFood>
{
// some code here...
public override HealthyFood Copy()
{
var baseCopy = base.Copy();
// extending the baseCopy with more data...
}
}
Now, I can easily instantiate and use the FoodContext<T> context like this:
using (var context = new FoodContext<HealthyFood>())
{
// some CRUD for "healthy food" goes here...
}
and the appropriate table is automatically created by EF in the database.
The problem is: when trying to call the "Enable-Migrations" command after updating the HealthyFood class (the model), I get notified by the Package Manager Console that "No context type was found in the assembly Food.Common".
My suspicion is that since the "Food.Common" does not contain a concrete (non generic) DbContext-based class, the "Enable-Migrations" thinks there's no context type inside this assembly at all.
So, how can I tell the Enable-Migrations that I want to update a concrete DbContext class (such as the FoodContext<HealthyFood>)?
Already tried Enable-Migrations -ContextTypeName Food.Common.FoodContext<HealthyFood> with no luck...

Handling specimen creation inconsistencies between AutoFixture and Moq

I am using AutoMoqCustomization in my test conventions.
Consider the code below. Everything works great until I add a constructor to one of the concrete classes. When I do, I get "could not find a parameterless constructor". We know AutoFixture doesn't have an issue with the constructor because it delivered me the test object one which proved to be assignable from IThings... no failure there. So it must be moq.
This makes some sense because I assume builder was generated by moq and passed into the GetCommands method. So I think I can see that control has been passed from AutoFixture to moq at that point.
That takes care of the why, but what should I do about it? Is there a way to instruct moq on how to deal with the ThingOne or is there a way to instruct AutoFixture to ignore moq for IThingBuilders and instead do something Fixtury?
public class TestClass
{
public interface IThingBuilders
{
T1 Build<T1>() where T1 : IThings;
}
public interface IThings
{
}
public class ThingOne : IThings
{
public ThingOne(string someparam)
{
}
}
public class ThingTwo : IThings
{
}
public class SomeClass
{
public List<IThings> GetCommands(IThingBuilders builder)
{
var newlist = new List<IThings>();
newlist.Add(builder.Build<ThingOne>());
newlist.Add(builder.Build<ThingTwo>());
return newlist;
}
}
[Theory, BasicConventions]
public void WhyCannotInstantiateProxyOfClass(ThingOne one, ThingTwo two, IThingBuilders builder, SomeClass sut)
{
Assert.IsAssignableFrom<IThings>(one);
Assert.IsAssignableFrom<IThings>(two);
var actual = sut.GetCommands(builder);
Assert.Equal(1, actual.OfType<ThingOne>().Count());
Assert.Equal(1, actual.OfType<ThingTwo>().Count());
}
}
As there's no extensibility point in Moq that enables AutoFixture to hook in and supply a value of ThingOne, there's not a whole lot you can do.
However, you can use the SetReturnsDefault<T> method of Moq. Modifying the above test would then be like this:
[Theory, BasicConventions]
public void WhyCannotInstantiateProxyOfClass(
ThingOne one, ThingTwo two, IThingBuilders builder, SomeClass sut)
{
Assert.IsAssignableFrom<IThings>(one);
Assert.IsAssignableFrom<IThings>(two);
Mock.Get(builder).SetReturnsDefault(one); // Add this to make the test pass
var actual = sut.GetCommands(builder);
Assert.Equal(1, actual.OfType<ThingOne>().Count());
Assert.Equal(1, actual.OfType<ThingTwo>().Count());
}
This is a bit easier than having to write a specific Setup/Returns pair, but not much. You could move that code to an AutoFixture Customization, but again, since this is a generic method on a a Mock instance, you'll explicitly need to call this for e.g. ThingOne in order to set the default for that return type. Not particularly flexible.

Resources