How to provide injection for method which is called in NinjectModule - c#-4.0

I have the following NinjectModule derived class:
class MainModule : NinjectModule
{
public override void Load()
{
Bind<IMyClass>().To<MyClass>();
Bind<IMainClass>().To<MainClass>().OnActivation((context,myClass) =>
{ myClass.Add("Something", context.Kernel.Get<IMyClass>()); });
}
}
My problem is that IKernel does not exposed the .Get<T> extension method.
Is there a pattern for doing this?
Caveats: I don't want to have to decorate my classes with Ninject attributes, as the Add is specific to how MainClass works I wanted all the code to do with its creation to be held in this module.
TIA

Hmmm, silly oversight in the end it seems. The extension methods reside in the Ninject namespace, using a module only requires that you are using Ninject.Modules;
Adding using Ninject; meant that the following was possible:
Bind<IMainClass>().To<MainClass>()
.OnActivation((context,myClass) =>
{
foreach(var n in context.Kernel.GetAll<IMyClass>())
{
myClass.Add("Something", n);
}
});
I'll leave this open for a bit to see if anyone has a better way of doing this.

Related

How can I run code in JUnit before Spring starts?

How can I run code in my #RunWith(SpringRunner.class) #SpringBootTest(classes = {...}) JUnit test before Spring starts?
This question has been asked several times (e.g. 1, 2) but was always "solved" by some configuration recommendation or other, never with a universal answer. Kindly don't question what I am about to do in that code but simply suggest a clean way to do it.
Tried so far and failed:
Extend SpringJUnit4ClassRunner to get a class whose constructor can run custom code before initializing Spring. Failed because super(testClass) must be called first thing and already does a whole lot of things that get in the way.
Extend Runner to get a class that delegates to SpringRunner instead of inheriting it. This class could run custom code in its constructor before actually instantiating the SpringRunner. However, this setup fails with obscure error messages like java.lang.NoClassDefFoundError: javax/servlet/SessionCookieConfig. "Obscure" because my test has no web config and thus shouldn't meddle with sessions and cookies.
Adding an ApplicationContextInitializer that is triggered before Spring loads its context. These things are easy to add to the actual #SpringApplication, but hard to add in Junit. They are also quite late in the process, and a lot of Spring has already started.
One way to do it is to leave out SpringRunner and use the equivalent combination of SpringClassRule and SpringMethodRule instead. Then you can wrap the SpringClassRule and do your stuff before it kicks in:
public class SomeSpringTest {
#ClassRule
public static final TestRule TestRule = new TestRule() {
private final SpringClassRule springClassRule =
new SpringClassRule();
#Override
public Statement apply(Statement statement, Description description) {
System.out.println("Before everything Spring does");
return springClassRule.apply(statement, description);
}
};
#Rule
public final SpringMethodRule springMethodRule = new SpringMethodRule();
#Test
public void test() {
// ...
}
}
(Tested with 5.1.4.RELEASE Spring verison)
I don't think you can get more "before" than that. As for other options you could also check out #BootstrapWith and #TestExecutionListeners annotations.
Complementing jannis' comment on the question, the option to create an alternative JUnit runner and let it delegate to the SpringRunner does work:
public class AlternativeSpringRunner extends Runner {
private SpringRunner springRunner;
public AlternativeSpringRunner(Class testClass) {
doSomethingBeforeSpringStarts();
springRunner = new SpringRunner(testClass);
}
private doSomethingBeforeSpringStarts() {
// whatever
}
public Description getDescription() {
return springRunner.getDescription();
}
public void run(RunNotifier notifier) {
springRunner.run(notifier);
}
}
Being based on spring-test 4.3.9.RELEASE, I had to override spring-core and spring-tx, plus javax.servlet's servlet-api with higher versions to make this work.

Using StructureMap[4.7.0] Setter Injection in my MVC5 Controller

I am trying to inject the IApplicationConfigurationSection implementation into this MVC5 Controller, so that I can have access to some of the information (various strings) from my web.config custom section in all of my views:
public class BaseController : Controller
{
public IApplicationConfigurationSection AppConfig { get; set; }
public BaseController()
{
ViewBag.AppConfig = AppConfig; // AppConfig is always null
}
}
I want to use setter injection so I don't have to clutter up my derived Controller constructors with parameters that they don't really care about.
Note: If there is a better way to inject base class dependencies, please let me know. I admit I may not be on the right track here.
In my Global.asax I load my StructureMap configurations:
private static IContainer _container;
protected void Application_Start()
{
_container = new Container();
StructureMapConfig.Configure(_container, () => Container ?? _container);
// redacted other registrations
}
My StructureMapConfig class loads my registries:
public class StructureMapConfig
{
public static void Configure(IContainer container, Func<IContainer> func)
{
DependencyResolver.SetResolver(new StructureMapDependencyResolver(func));
container.Configure(cfg =>
{
cfg.AddRegistries(new Registry[]
{
new MvcRegistry(),
// other registries redacted
});
});
}
}
My MvcRegistry provides the mapping for StructureMap:
public class MvcRegistry : Registry
{
public MvcRegistry()
{
For<BundleCollection>().Use(BundleTable.Bundles);
For<RouteCollection>().Use(RouteTable.Routes);
For<IPrincipal>().Use(() => HttpContext.Current.User);
For<IIdentity>().Use(() => HttpContext.Current.User.Identity);
For<ICurrentUser>().Use<CurrentUser>();
For<HttpSessionStateBase>()
.Use(() => new HttpSessionStateWrapper(HttpContext.Current.Session));
For<HttpContextBase>()
.Use(() => new HttpContextWrapper(HttpContext.Current));
For<HttpServerUtilityBase>()
.Use(() => new HttpServerUtilityWrapper(HttpContext.Current.Server));
For<IApplicationConfigurationSection>()
.Use(GetConfig());
Policies.SetAllProperties(p => p.OfType<IApplicationConfigurationSection>());
}
private IApplicationConfigurationSection GetConfig()
{
var config = ConfigurationManager.GetSection("application") as ApplicationConfigurationSection;
return config; // this always returns a valid instance
}
}
I have also "thrown my hands up" and tried using the [SetterProperty] attribute on the BaseController - that technique failed as well.
Despite my best efforts to find a solution, the AppConfig property in my controller's constructor is always null. I thought that
`Policies.SetAllProperties(p => p.OfType<IApplicationConfigurationSection>());`
would do the trick, but it didn't.
I have found that if I discard setter injection and go with constructor injection, it works as advertised. I'd still like to know where I'm going wrong, but I'd like to stress that I'm not a StructureMap guru - there may be a better way to avoid having to constructor-inject my base class dependencies. If you know how I should be doing this but am not, please share.
While constructor injection in this scenario appears to be the better solution to the stated problem as it follows The Explicit Dependencies Principle
Methods and classes should explicitly require (typically through method parameters or constructor parameters) any collaborating objects they need in order to function correctly.
The mention of only needing to access the AppConfig in your views leads me to think that this is more of an XY problem and a cross cutting concern.
It appears that the controllers themselves have no need to use the dependency so stands to reason that there is no need to be injecting them into the controller explicitly just so that the dependency is available to the View.
Consider using an action filter that can resolve the dependency and make it available to the View via the same ViewBag as the request goes through the pipeline.
public class AccessesAppConfigAttribute : ActionFilterAttribute {
public override void OnActionExecuting(ActionExecutingContext filterContext) {
var resolver = DependencyResolver.Current;
var appConfig = (IApplicationConfigurationSection)resolver.GetService(typeof(IApplicationConfigurationSection));
filterContext.Controller.ViewBag.AppConfig = appConfig;
}
}
This now makes the required information available to the views with out tight coupling of the controllers that may have a use for it. Removing the need to inject the dependency into derived classes.
Either via adorning Controller/Action with the filter attribute
[AccessesAppConfig] //available to all its actions
public class HomeController : Controller {
//[AccessesAppConfig] //Use directly if want to isolate to single action/view
public ActionResult Index() {
//...
return View();
}
}
or globally for all requests.
public class FilterConfig {
public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
filters.Add(new AccessesAppConfigAttribute());
}
}
At this point it really does not matter which IoC container is used. Once the dependency resolver has been configured, Views should have access to the required information in the ViewBag

Parameter specified as non-null is null when using Mokito anyObject() on Kotlin function

My code as below, refering to the solution in https://stackoverflow.com/a/30308199/3286489
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
import org.mockito.Mockito.*
class SimpleClassTest {
private fun <T> anyObject(): T {
Mockito.anyObject<T>()
return uninitialized()
}
private fun <T> uninitialized(): T = null as T
lateinit var simpleObject: SimpleClass
#Mock lateinit var injectedObject: InjectedClass
#Before
fun setUp() {
MockitoAnnotations.initMocks(this)
}
#Test
fun testSimpleFunction() {
simpleObject = SimpleClass(injectedObject)
verify(injectedObject).settingDependentObject(anyObject())
}
}
I still have the below error
java.lang.IllegalArgumentException: Parameter specified as non-null is null: method my.package.InjectedClass.settingDependentObject, parameter dependentObject
Did I miss anything?
UPDATED
Below is the code tested (simplest form and working)
class SimpleClass(val injectedClass: InjectedClass) {
fun simpleFunction() {
injectedClass.settingDependentObject(DependentClass(Response.Builder().build()))
}
}
open class DependentClass(response: Response) {
}
open class InjectedClass() {
lateinit var dependentObject: DependentClass
fun settingDependentObject(dependentObject: DependentClass) {
this.dependentObject = dependentObject
}
}
By default Kotlin classes and members are final. Mockito cannot mock final classes or methods.
Thus when you write:
verify(injectedObject).settingDependentObject(anyObject())
the real implementation is called which requires non null argument.
To fix that either open your class and method or, even better, change SimpleClass to accept an interface as its constructor argument and mock the interface instead.
There is a project specifically to help deal with Kotlin "closed by default" in unit testing with Mockito. For JUNIT, you can use the kotlin-testrunner which is an easy way to make any Kotlin test automatically open up classes for testing as they are loaded by the classloader. Usage is simple, just add one annotation of #RunWith(KotlinTestRunner::class), for example:
#RunWith(KotlinTestRunner::class)
class MyKotlinTestclass {
#Test
fun test() {
...
}
}
This is thoroughly covered in the article Never say final: mocking Kotlin classes in unit tests
This covers your use case in an automatic way by allowing all classes to be mocked that otherwise would not be allowed.
I ran into the same issue with Mockito when using RETURNS_DEEP_STUBS. It seems like nulls are still returned for nested objects, even when using the kotlin-allopen plugin.
Please check out and comment on this issue on Mockito if you're having the same problem.
You can use this function instead
inline fun <reified T : Any> any(): T = Mockito.any(T::class.java) ?: T::class.java.newInstance()

Unable to get default constructor for Integration class ninject

I'm new on using ninject and Dependency Injection, and have a problem using it.
I try to using Ninject on my class libray, and building an integration tests.
now, I see in many example that, for using ninject is just specified the DI Module like this:
Public Class DIModule : NinjectModule
public override void Load()
{
Bind<IUSAServices>().To<USAServices>();
}
And then on my test class, I try to call my dependency is like this:
[TestClass]
public class USAIntegrationTests
{
private readonly IUSAServices _usaService;
public USAIntegrationTests(IUSAServices usaServices)
{
_usaService = usaServices;
}
[TestMethod]
public void ValidateUserTests()
{
Assert.IsTrue(_usaService.ValidateUser("username1", "password1"));
}
}
And Getting this error:
Unable to get default constructor for class USATests.IntegrationTests.USAIntegrationTests.
However I read the documentation and tried like this:
[TestClass]
public class USAIntegrationTests
{
private readonly IUSAServices _usaService;
public USAIntegrationTests()
{
using (IKernel kernel = new StandardKernel(new DIModule()))
{
_usaService = kernel.Get<IUSAServices>();
}
}
[TestMethod]
public void ValidateUserTests()
{
Assert.IsTrue(_usaService.ValidateUser("mantab", "banget"));
}
}
The test is works properly.
My question is, why I getting that error? is that some way to get around it?
Thanks in advance.
Unit test frameworks require your test classes to have a default constructor. You usually can't integrate DI containers with them. Instead of using constructor injection, you will have to call the container directly from your code, although for unit tests you should typically not have a container at all (for integration tests however, this is okay).
You can add a paramterless constructor for the class. It worked for me.

looking for a proper way to implement my generic factory

I'm struggling with implementing a factory object. Here's the context :
I've in a project a custom store. In order to read/write records, I've written this code in a POCO model/separated repository:
public class Id { /* skip for clarity*/} // My custom ID representation
public interface IId
{
Id Id { get; set; }
}
public interface IGenericRepository<T> where T : IId
{
T Get(Id objectID);
void Save(T #object);
}
public interface IContext
{
TRepository GetRepository<T, TRepository>()
where TRepository : IGenericRepository<T>
where T:IId;
IGenericRepository<T> GetRepository<T>()
where T:IId;
}
My IContext interface defines two kind of repositories.
The former is for standard objects with only get/save methods, the later allows me to define specifics methods for specific kind of objects. For example :
public interface IWebServiceLogRepository : IGenericRepository<WebServiceLog>
{
ICollection<WebServiceLog> GetOpenLogs(Id objectID);
}
And it the consuming code I can do one of this :
MyContext.GetRepository<Customer>().Get(myID); --> standard get
MyContext.GetRepository<WebServiceLog, IWebServiceLogRepository>().GetOpenLogs(myID); --> specific operation
Because most of objects repository are limited to get and save operations, I've written a generic repository :
public class BaseRepository<T> : IGenericRepository<T>
where T : IId, new()
{
public virtual T Get(Id objectID){ /* provider specific */ }
public void Save(T #object) { /* provider specific */ }
}
and, for custom ones, I simply inherits the base repository :
internal class WebServiceLogRepository: BaseRepository<WebServiceLog>, IWebServiceLogRepository
{
public ICollection<WebServiceLog> GetByOpenLogsByRecordID(Id objectID)
{
/* provider specific */
}
}
Everything above is ok (at least I think it's ok). I'm now struggling to implement the MyContext class. I'm using MEF in my project for other purposes. But because MEF doesn't support (yet) generic exports, I did not find a way to reach my goal.
My context class is looking like by now :
[Export(typeof(IContext))]
public class UpdateContext : IContext
{
private System.Collections.Generic.Dictionary<Type, object> m_Implementations;
public UpdateContext()
{
m_Implementations = new System.Collections.Generic.Dictionary<Type, object>();
}
public TRepository GetRepository<T, TRepository>()
where T : IId
where TRepository : IGenericRepository<T>
{
var tType = typeof(T);
if (!m_Implementations.ContainsKey(tType))
{
/* this code is neither working nor elegant for me */
var resultType = AppDomain.CurrentDomain.GetAssemblies().SelectMany(
(a) => a.GetTypes()
).Where((t)=>t.GetInterfaces().Contains(typeof(TRepository))).Single();
var result = (TRepository)resultType.InvokeMember("new", System.Reflection.BindingFlags.CreateInstance, null, null, new object[] { this });
m_Implementations.Add(tType, result);
}
return (TRepository)m_Implementations[tType];
}
public IGenericRepository<T> GetRepository<T>() where T : IId
{
return GetRepository<T, IGenericRepository<T>>();
}
}
I'd appreciate a bit of help to unpuzzle my mind with this quite common scenario
Not sure if I've understood you correctly, but I think you're perhaps over complicating things. To begin with, make sure you've designed your code independent of any factory or Dependency Injection framework or composition framework.
For starters lets look at what you want your calling code to look like, this is what you said:
MyContext.GetRepository<Customer>().Get(myID); --> standard get
MyContext.GetRepository<WebServiceLog, IWebServiceLogRepository>().GetOpenLogs(myID);
You don't have to agree with my naming choices below, but it indicates what I undertand from your code, you can tell me if I'm wrong. Now, I feel like the calling would be simpler like this:
RepositoryFactory.New<IRepository<Customer>>().Get(myId);
RepositoryFactory.New<IWebServiceLogRepository>().GetOpenLogs(myId);
Line 1:
Because the type here is IRepository it's clear what the return type is, and what the T type is for the base IRepository.
Line 2:
The return type here from the factory is IWebServiceLogRepository. Here you don'y need to specify the entity type, your interface logically already implements IRepository. There's no need to specify this again.
So your interface for these would look like this:
public interface IRepository<T>
{
T Get(object Id);
T Save(T object);
}
public interface IWebServiceLogRepository: IRepository<WebServiceLog>
{
List<WebServiceLog> GetOpenLogs(object Id);
}
Now I think the implementations and factory code for this would be simpler as the factory only has to know about a single type. On line 1 the type is IRepository, and in line 2, IWebServiceLogRepository.
Try that, and try rewriting your code to simply find classes that implement those types and instantiating them.
Lastly, in terms of MEF, you could carry on using that, but Castle Windsor would really make things much simpler for you, as it lets you concentrate on your architecture and code design, and its very very simple to use. You only ever reference Castle in your app startup code. The rest of your code is simply designed using the Dependency Injection pattern, which is framework agnostic.
If some of this isn't clear, let me know if you'd like me to update this answer with the implementation code of your repositories too.
UPDATE
and here's the code which resolves the implementations. You were making it a bit harder for yourself by not using the Activator class.
If you use Activator and use only one Generic parameter as I've done in the method below, you should be ok. Note the code's a bit rough but you get the idea:
public static T GetThing<T>()
{
List<Type> assemblyTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes()).ToList();
Type interfaceType = typeof(T);
if(interfaceType.IsGenericType)
{
var gens = interfaceType.GetGenericArguments();
List<Type> narrowed = assemblyTypes.Where(p => p.IsGenericType && !p.IsInterface).ToList();
var implementations = new List<Type>();
narrowed.ForEach(t=>
{
try
{
var imp = t.MakeGenericType(gens);
if(interfaceType.IsAssignableFrom(imp))
{
implementations.Add(imp);
}
}catch
{
}
});
return (T)Activator.CreateInstance(implementations.First());
}
else
{
List<Type> implementations = assemblyTypes.Where(p => interfaceType.IsAssignableFrom(p) && !p.IsInterface).ToList();
return (T)Activator.CreateInstance(implementations.First());
}
}

Resources