Inject a dependency in an existing instance - ninject

I have the following classes:
The class to be injected with a dependency
public class ToBeInjected
{
[Inject]
public void InjectCommandParameters( IInjectParameters parameters )
{
// some set code here
}
}
The dependency to be injected that implements IInjectParameters
and an injector
public class Injector
{
public void SetParameters( ToBeInjected statement, IInjectParameters parameters )
{
statement.InjectCommandParameters(parameters);
}
}
so what I try to achieve statement.InjectCommandParameters(parameters) by using ninject.

Related

Arquillian with Mockito and CDI

Is it possible to create spy(mock) object in testing class?
Here is tested class.
#Stateless
#Slf4j
public class UserDao {
#Inject
private TestBean testBean;
public String mock() {
return testBean.mock();
}
public String notMock() {
return testBean.notMock();
}
}
TestBean code
#Stateless
#Slf4j
public class TestBean {
public String notMock() {
return "NOT MOCK";
}
public String mock() {
return "IMPLEMENTED MOCK";
}
}
Here's my test
#RunWith(Arquillian.class)
public class UserDataTest {
#Rule
public ExpectedException thrown = ExpectedException.none();
#Inject
private UserDao userDao;
#Deployment
protected static Archive createWar() {
File[] dependencies = Maven.configureResolver()
.withRemoteRepo("nexus-remote", "http://maven.wideup.net/nexus/content/groups/public/", "default")
.withRemoteRepo("nexus-release", "http://maven.wideup.net/nexus/content/repositories/releases/", "default")
.resolve(
"org.slf4j:slf4j-simple:1.7.7",
"eu.bitwalker:UserAgentUtils:1.15",
"org.mockito:mockito-all:1.10.8"
).withoutTransitivity().asFile();
return ShrinkWrap
.create(WebArchive.class, "pass.jpa.war")
.addAsWebInfResource("jbossas-ds.xml")
.addAsWebInfResource("jboss-deployment-structure.xml")
.addAsLibraries(
PassApiDeployments.createDefaultDeployment(),
PassUtilLibrary.createDefaultDeployment(),
PassJpaDeployments.createDefaultDeployment()
).addAsLibraries(dependencies);
}
#Test
public void testMock() {
assertEquals("MOCK", userDao.mock());
}
#Test
public void testNotMock() {
assertEquals("NOT MOCK", userDao.notMock());
}
}
I'd like to create a spy object on TestBean to change result on method test() of this bean.
So is it possible to create TestBean spy in UserDao.
I solve some problems through producer like this.
#Singleton
public class MockFactory {
#Produces
#ArquillianAlternative
public TestBean getTestBean() {
return when(mock(TestBean.class).mock()).thenReturn("MOCK").getMock();
}
}
But in this example I need create on Bean completely on my own. And if it is bean with additional dependencies and thus i will manage all dependencies.
As far as I know, its not possible to use a mocking framework in combination with arquillian ...
I haven't used it myself, but this Arquillian extension seems to be specifically designed to support Mockito Spy objects in an Arquillian test: https://github.com/topikachu/arquillian-extension-mockito/

Ninject request scope and callback

I have a problem with Ninject in a MVC project using Owin.
I have a generic class for UnitOfWork that is not specific to my project :
public class UnitOfWork : IUnitOfWork
{
public UnitOfWork(DbContext context)
{...}
}
I define two repositories using my custom DbContext :
public UserRepository : IUserRepository
{
public UserRepository(MyEntities context)
{...}
}
public OrderRepository : IOrderRepository
{
public OrderRepository(MyEntities context)
{...}
}
Then I have a ApiController which use the unit of work and the repositories.
public OrderController : ApiController
{
public OrderController(IUnitOfWork uow, IUserRepository userRepository, IOrderRepository orderRepository)
{...}
}
I configure my Ninject kernel within a module. My bindings are with a request scope.
public class MyModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
// Bind all the repositories
this.Bind(x =>
x.FromAssembliesMatching("*.Repositories")
.SelectAllClasses()
.BindDefaultInterface()
.Configure(c => c.InRequestScope()));
// Bind the DbContext of the application
this.Bind<MyEntities>()
.ToSelf()
.InRequestScope();
// To bind the UnitOfWork, I need to specify the real DbContext to use. For that I use a callback which provide argument to constructor :
this.Bind<IUnitOfWork>()
.To<UnitOfWork>()
.InRequestScope()
.WithConstructorArgument("context", GetContext);
}
private Object GetContext(IContext context, ITarget target)
{
IResolutionRoot resolver;
ActivationBlock scope;
scope = context.Request.GetScope() as ActivationBlock;
resolver = scope ?? (IResolutionRoot)context.Kernel;
var o = resolver.Get<MyEntities>();
var o2 = resolver.Get<MyEntities>();
var same = Object.ReferenceEquals(o, o2);
return o;
}
}
Then I activate Ninject with Owin like this in the Startup class :
public class Startup
{
public void Configuration(IAppBuilder app)
{
...
app.UseNinjectMiddleware(Startup.CreateKernel);
var config = new HttpConfiguration();
...
app.UseNinjectWebApi(config);
}
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Load(new MyModule());
return kernel;
}
}
It seems good but there is a big problem. The repositories share the same DbContext, but the DbContext in the UnitOfWork is a different instance.
In the function GetContext, the scope is always null, so the MyContext instance is retrieved from the kernel. The boolean variable same is always false. The problem is here. The Get function of the kernel return a new instance, instead of the instance of the request scope.
Not sure if you still need this... but you can bind the dbcontext to self and then ask for it when you want to use it.
Bind<ApplicationDbContext>().ToSelf();
Bind<IUserStoreGuid<User>>().To<UserStoreGuid<User>>().WithConstructorArgument("context", Kernel.GetService(typeof(ApplicationDbContext)));
Although the connection string in the app is called "DefautConnection", you need to use "context" because that is how it is called in the constructor argument. I got this from here

Castle windsor wire generic irepository with 2 types

Hi I am trying to change a code example found here
http://imar.spaanjaars.com/577/aspnet-n-layered-applications-implementing-a-repository-using-ef-code-first-part-5
In his example he uses structure map, when I converted it to windsor I can get it to work with the one repository using the following.
container.Register(Component.For<IUnitOfWorkFactory>().ImplementedBy<EFUnitOfWorkFactory>(),
Component.For<IUnitOfWork>().ImplementedBy<EFUnitOfWork>(),
Component.For<Model.Repositories.IPeopleRepository>().ImplementedBy<PeopleRepository>().LifestyleTransient());
But what I really want to do is to map all the irepository based interfacees to thier implementation.
Here is the IRepository, T is the entity, K is the prmiary key type
public interface IRepository<T, K> where T : class
{
}
Its implementation Is
public abstract class Repository<T> : IRepository<T, int>, IDisposable where T : DomainEntity<int>
{
}
My controller has the interface IPeopleRepository as a constructor paramerter.
public interface IPeopleRepository : IRepository<Person, int>
{
}
public class PeopleRepository : Repository<Person>, IPeopleRepository
{
}
I want to have one register to register all repositories, something like this, but it wont match and i get the error Service 'Spaanjaars.ContactManager45.Model.Repositories.IPeopleRepository' which was not registered
container.Register(Component.For(typeof(IRepository<,>))
.ImplementedBy(typeof(Repository<>))
.LifestylePerWebRequest());
What am i missing in regards to this? is it because my irepository has 2 generic types?
In order to map all the IRepository based interfaces to their implementations .WithService.AllInterfaces() should be used.
This registration should solve your issue.
container.Register(
Classes.FromThisAssembly()
.BasedOn(typeof(IRepository<,>))
.WithService.AllInterfaces()
.LifestylePerWebRequest());
There are some tests to test it. I claim they are green.
[TestClass]
public class InstallerTest
{
private IWindsorContainer container;
[TestInitialize]
public void Init()
{
container = new WindsorContainer().Install(new Installer());
}
[TestMethod]
public void ResilveTest_ResolvesViaIRepository()
{
// act
var repository = container.Resolve<IRepository<Person, int>>();
// assert
repository.Should().BeOfType<PeopleRepository>();
}
[TestMethod]
public void ResilveTest_ResolvesViaIPeopleRepository()
{
// act
var repository = container.Resolve<IPeopleRepository>();
// assert
repository.Should().BeOfType<PeopleRepository>();
}
}
public class Installer : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Classes.FromThisAssembly()
.BasedOn(typeof(IRepository<,>))
.WithService.AllInterfaces()
.LifestylePerThread());
}
}

Injecting my UnitOfWork into my Repository Constructor

Im very new but on a quest to learn nhibernate and DI with structuremap so am making an app to test everything out.
I am having some problems injecting my unitofwork into my base repository. I create a unitofwork on every request then either commit or rollback at the end. But when tryin to inject into my base repository its always null when i go to use it in my methods. More specifically i get this error: "Object reference not set to an instance of an object". Any ideas what im doing wrong and if this is the correct route i should be going?
Many thanks in advance.
Base Repository:
public abstract class Repository<T> : IRepository<T>
{
public readonly IUnitOfWork _unitOfWork;
public Repository(IUnitOfWork UnitOfWork)
{
UnitOfWork = _unitOfWork;
}
public Repository() {}
public void Save(T obj)
{
_unitOfWork.CurrentSession.Save(obj);
}
}
StructureMap registry thats set in my application_start:
public class NHibernateRegistry : Registry
{
public NHibernateRegistry()
{
For<IUnitOfWork>().HybridHttpOrThreadLocalScoped().Use<UnitOfWork>();
For<ISession>().HybridHttpOrThreadLocalScoped().Use(context => context.GetInstance<ISessionFactory>().OpenSession());
For<ISessionFactory>().Singleton().Use(NHibernateSessionFactory.GetSessionFactory());
}
}
Update:
The baserepository is inherited by specific repositorys ie ArticleRepository then im injecting that into my aspx pages on application_start. Then my aspx page inherits a basepage where the buildUp takes place. And i access the repository like this:
public IArticleRepository ArticleRepo { get; set; }
public void SaveThing()
{
ArticleRepo.Save(object);
}
This gets called on application_start:
public class Bootstrapper
{
public static void BootStrap()
{
ObjectFactory.Configure(x =>
{
x.AddRegistry<NHibernateRegistry>();
x.AddRegistry<WebRegistry>();
});
}
}
And in the webregistry:
For<IArticleRepository>().Use<ArticleRepository>();
There is a good chance your ArticleRepository doesn't have a constructor that takes an IUnitOfWork as a parameter make sure you have the following
public class ArticleRepository : Repository<Article>
{
public ArticleRepository(IUnitOfWork unitOfWork) : base(unitOfWork)
{
}
...
}
Remember Strcuture map uses the greediest constructor on the class that it instantiates. Since your abstract repository class will never be instantiated it will not use its constructors. I would also suggest not having any default constructors if your classes need to have their dependencies injected that way. Less chance for errors that way.
public readonly IUnitOfWork _unitOfWork;
public Repository(IUnitOfWork UnitOfWork)
{
UnitOfWork = _unitOfWork;
}
I think you mean to write
public readonly IUnitOfWork _unitOfWork;
public Repository(IUnitOfWork UnitOfWork)
{
_unitOfWork = UnitOfWork;
}
You were assigning the local variable to the parameter instead of the parameter to the local variable.
Edit: Also you should write your parameter with a lowercase U 'unitOfWork' instead of 'UnitOfWork'

Avoiding Service Locator with AutoFac 2

I'm building an application which uses AutoFac 2 for DI. I've been reading that using a static IoCHelper (Service Locator) should be avoided.
IoCHelper.cs
public static class IoCHelper
{
private static AutofacDependencyResolver _resolver;
public static void InitializeWith(AutofacDependencyResolver resolver)
{
_resolver = resolver;
}
public static T Resolve<T>()
{
return _resolver.Resolve<T>();
}
}
From answers to a previous question, I found a way to help reduce the need for using my IoCHelper in my UnitOfWork through the use of Auto-generated Factories. Continuing down this path, I'm curious if I can completely eliminate my IoCHelper.
Here is the scenario:
I have a static Settings class that serves as a wrapper around my configuration implementation. Since the Settings class is a dependency to a majority of my other classes, the wrapper keeps me from having to inject the settings class all over my application.
Settings.cs
public static class Settings
{
public static IAppSettings AppSettings
{
get
{
return IoCHelper.Resolve<IAppSettings>();
}
}
}
public interface IAppSettings
{
string Setting1 { get; }
string Setting2 { get; }
}
public class AppSettings : IAppSettings
{
public string Setting1
{
get
{
return GetSettings().AppSettings["setting1"];
}
}
public string Setting2
{
get
{
return GetSettings().AppSettings["setting2"];
}
}
protected static IConfigurationSettings GetSettings()
{
return IoCHelper.Resolve<IConfigurationSettings>();
}
}
Is there a way to handle this without using a service locator and without having to resort to injecting AppSettings into each and every class? Listed below are the 3 areas in which I keep leaning on ServiceLocator instead of constructor injection:
AppSettings
Logging
Caching
I would rather inject IAppSettings into every class that needs it just to keep them clean from the hidden dependency on Settings. Question is, do you really need to sprinkle that dependency into each and every class?
If you really want to go with a static Settings class I would at least try to make it test-friendly/fakeable. Consider this:
public static class Settings
{
public static Func<IAppSettings> AppSettings { get; set; }
}
And where you build your container:
var builder = new ContainerBuilder();
...
var container = builder.Build();
Settings.AppSettings = () => container.Resolve<IAppSettings>();
This would allow to swap out with fakes during test:
Settings.AppSettings = () => new Mock<IAppSettings>().Object;
Now the AppSettings class (which I assume there is only one of) you could do with regular constructor injection. I assume also that you really want to do a resolve on each call to your settings properties, thus injecting a factory delegate that retrieves an instance when needed. If this is not needed you should of course inject the IConfigurationSettings service directly.
public class AppSettings : IAppSettings
{
private readonly Func<IConfigurationSettings> _configurationSettings;
public AppSettings(Func<IConfigurationSettings> configurationSettings)
{
_configurationSettings = configurationSettings;
}
public string Setting1
{
get
{
return _configurationSettings().AppSettings["setting1"];
}
}
public string Setting2
{
get
{
return _configurationSettings().AppSettings["setting2"];
}
}
}