Ninject, Providers and Activator.CreateInstance - ninject

I'm fairly new to Ninject, but I have successfully managed to use it for DI using a custom provider.
The binding is initialised as follows
kernel = new StandardKernel();
kernel.Bind<IPatientRecordLocator>().ToProvider<PatientRecordLocatorProvider>();
and in the custom provider I call Activator.CreateInstance like so
protected override IPatientRecordLocator CreateInstance(IContext context)
{
var name = ConfigurationManager.AppSettings["PatientRecordLocator"];
var typeName = name.Split(',')[0];
var assemblyName = name.Split(',')[1];
return Activator.CreateInstance(assemblyName, typeName).Unwrap() as IPatientRecordLocator;
}
(yes, I am aware that there is no error handling, etc. in the code above :) )
and all this works like a charm.
Now, the problem I'm facing is when I introduce a new class that I wish to inject into instances of IPatientRecordLocator. The problem occurs when I add a constructor like the following to e.g. one of these classes
[Inject]
public MockPatientRecordLocator (IContactAdapter contactAdapter)
{
...
}
Then, for Activator.CreateInstance to work I also have to add a parameterless constructor to class MockPatientRecordLocator, i.e.
public MockPatientRecordLocator()
{
}
So, my question is: how can I make Ninject inject an instance of a class that implements IContactAdapter into e.g. MockPatientRecordLocator? I've tried method injection, but to no avail.
I forgot to explain that what I'm trying to achieve is a kind of chained injection where an instance of class PatientRecordSummary gets injected with an instance of MockPatientRecordLocator (using constructor injection) and said instance of MockPatientRecordLocator should get injected with an instance of IContactAdapter (again using constructor injection (if possible)). The first part of the chain works, the second doesn't.

Not bad for a first question!
You want to use the Bind(Type) overload to allow registration of stuff that you dont have statically available in the context of your Load() code - do the stuff you're doing in your provider (i.e., resolving the Type) up-front. This will allow Ninject to do the object instantiation (without any requirement for a default .ctor)
IIRC two or 3 of my most recent answers also touch on this discovery/loading stuff, and have examples that should be relevant to your case.
(And you wont need to resort to [Inject] attributes when you've gotten to remove things)

Related

Optaplanner: prevent custom List from beeing cloned by FieldAccessingSolutionCloner

I have a #PlanningSolution class, that has one field with a custom List implementation as type.
When solving I run into the following issue (as described in the optaplanner documentation):
java.lang.IllegalStateException: The cloneCollectionClass (class java.util.ArrayList) created for originalCollectionClass (class Solution$1) is not assignable to the field's type (class CustomListImpl).
Maybe consider replacing the default SolutionCloner.
As this field has no impact on planning, can I prevent FieldAccessingSolutionCloner from trying to clone that particular field e.g. by adding some annotation? I dont want to provide a complete custom SolutionCloner.
When inspecting the sources of FieldAccessingSolutionCloner I found out that I only needed to override the method retrieveCachedFields(...) or constructCloneCollection(...) so I tried to extend FieldAccessingSolutionCloner but then I need a public no-args-constructor. There I dont know how to initialise the field solutionDescriptor in the no-args-constructor to use my ExtendedFieldAccessingSolutionCloner as solution cloner.
If the generic solution cloner decided to clone that List, there is probably a good reason for it do so: one of the the elements in that list probably has a reference to a planning entity or the planning solution - and therefore the entire list needs to be planning cloned.
If that's not the case, this is a bug in OptaPlanner. Please provide the classes source code of the class with that field and the CustomListImpl class too, so we can reproduce and fix it.
To supply a custom SolutionCloner, follow the docs which will show something like this (but this is a simple case without chained variables, so it's easy to get right, but solution cloning is notoriously difficult!).
#PlanningSolution(solutionCloner = VaccinationSolutionCloner.class)
public class VaccinationSolution {...}
public class VaccinationSolutionCloner implements SolutionCloner<VaccinationSolution> {
#Override
public VaccinationSolution cloneSolution(VaccinationSolution solution) {
List<PersonAssignment> personAssignmentList = solution.getPersonAssignmentList();
List<PersonAssignment> clonedPersonAssignmentList = new ArrayList<>(personAssignmentList.size());
for (PersonAssignment personAssignment : personAssignmentList) {
PersonAssignment clonedPersonAssignment = new PersonAssignment(personAssignment);
clonedPersonAssignmentList.add(clonedPersonAssignment);
}
return new VaccinationSolution(solution.getVaccineTypeList(), solution.getVaccinationCenterList(), solution.getAppointmentList(),
solution.getVaccinationSlotList(), clonedPersonAssignmentList, solution.getScore());
}
}

Ninject ToFactory not working with parameters

I am attempting to use the ToFactory extension for Ninject, but am running into a few problems.
If I have a constructor like this:
public ListenerReader(IDepen1 depen1, IDepen2 depen2, UdpClient client, DataReceiveModes dataReceiveMode, int receivePort)
{
}
And then I create a factory to automatically create the items like this:
public interface IListenerReaderFactory
{
ListenerReader CreateListenerReader(UdpClient client, DataReceiveModes dataReceiveMode, int receivePort);
}
I receive an activation error when I try to call the injected factory:
Error activating int
No matching bindings are available, and the type is not self-bindable.
It seems like Ninject does not like to inject primitive types in the factories. I have also seen this same error but with the string type in another factory?
If this does not work do I have to separate the parameters into a called method?
EDIT:
It appears that the type in question was being injected outside of the factory. Thus Ninject was trying to create bindings for the enum and int types which failed.
The problem was the factory was not being called and the type was being injected directly instead.

Dependency Injection - what is the difference between these two codes? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have been trying to understand dependency injection and I have been making progress but
I will like to know the benefit/difference/importance of these code. They look the same but different approach
//dependency injection - (as was claimed)
Customer customer = new Customer(10);
IOrderDAO orderDAO = new OrderDAO();
customer.setOrderDAO(orderDAO);
customer.getOrdersByDate();
OR
//Unknown Pattern - Please what pattern is this?
Customer customer = new Customer(10);
IOrderDAO orderDAO = new OrderDAO();
orderDAO.getOrderByDate(customer.id);
What's wrong with the second approach?
Thanks.
Neither one looks like dependency injection to me; there shouldn't be calls to new.
Dependency injection is done by a bean factory that's wired with all the dependencies. It instantiates the beans and gives them their dependencies.
I see no bean factory here at all. It's a long way to dependency injection.
The Customer gets the OrderDAO in the first example using the setter. The first one says that the Customer has to expose persistence methods in its API. It's responsible for saving its Orders. I'd say it's a poor separation of concerns, because now Customers have to know about Orders.
The second one keeps Customer separate from OrderDAO. You pass a Customer ID to the OrderDAO and have it save Orders on that Customer's behalf. I think it's a better separation of concerns.
But neither one is a good example of dependency injection.
The first and best description of DI came from Martin Fowler. I'd recommend that you read this carefully:
http://martinfowler.com/articles/injection.html
It's eight years old, but still spot on.
Neither of them is proper dependency injection example. Those are rather examples of data access patterns.
The first one is an example of active record pattern. Setting orderDAO as a dependency for customer entity we could call property or setter injection.
The second example could be repository pattern. Dependency pattern here would be method injection, which translates to common invoking method with some parameters (parameters here are dependencies for method).
Good way to start learning DI pattern would be reading this book. There are also many online resources like those videos:
http://www.youtube.com/watch?v=RlfLCWKxHJ0
http://www.youtube.com/watch?v=-FRm3VPhseI&feature=relmfu
http://www.youtube.com/watch?feature=player_embedded&v=hBVJbzAagfs
I would also recommend looking for Dependency Inversion Principle in google (it's not the same as dependency injecion).
It's an odd example, but the first one demonstrates what a dependency injection container would do and the second one demonstrates one object passing an argument to another object. The first embeds its dependencies as instance variables of the calling class; the second is more procedural in nature. Neither is wrong, per se. It depends on how complex your dependencies are and how you want to manage code.
Looking just at the injector code you provided, it's not immediately obvious why you'd ever want to use dependency injection. But consider a more complex (and more typical) example for a moment.
CustomerService:
public class CustomerService implements ICustomerService {
private IOrderDAO orderDao;
public void setOrderDAO(IOrderDAO orderDao) {
this.orderDao = orderDao;
}
public Order getOrderByDate(Integer customerId, Date date) {
return this.orderDao.findOrderByDate(customerId, date);
}
}
OrderDAO (default implementation):
public OrderDAO implements IOrderDAO {
private javax.sql.DataSource dataSource;
public void setDataSource(javax.sql.DataSource dataSource) {
this.dataSource = dataSource;
}
public Order findOrderByDate(Integer customerId, Date date) {
...
}
}
StubOrderDAO (stub implementation):
public StubOrderDAO implements IOrderDAO {
public Order findOrderByDate(Integer customerId, Date date) {
return new HardCodedOrder(); // this class would extend or implement Order
}
}
At runtime, instances of CustomerService won't have any idea which implementation of IOrderDAO is being used. That means that you could very easily, for instance, bootstrap a unit test for CustomerService by initializing it with StubOrderDAO (which always returns a hard-coded customer). Likewise, your DataSource implementation may vary (either a mock data source or one which is different in different runtime environments).
So an injector intended for production use might look like:
// instantiate
CustomerService service = new CustomerService();
OrderDAO dao = new OrderDAO();
javax.sql.dataSource dataSource = jndiContext.lookup("java:comp/env/MyDataSource");
// initialize
dao.setDataSource(dataSource);
service.setOrderDAO(dao);
return service;
Whereas an injector for using a local (test) data source might look like:
// instantiate
CustomerService service = new CustomerService();
OrderDAO dao = new OrderDAO();
javax.sql.dataSource dataSource = new DriverManagerDataSource("jdbc:sqlserver:yadayada...", "myUsername", "myPassword");
// initialize
dao.setDataSource(dataSource);
service.setOrderDAO(dao);
return service;
And an injector for an integration test might look like:
// instantiate
CustomerService service = new CustomerService();
OrderDAO dao = new StubOrderDAO();
// initialize
service.setOrderDAO(dao);
return service;
So it's essentially a way to implement good layering and separation of concerns, i.e. the way you access the database is independent of how you access the data to create the domain model, and both are independent of any aggregation or business logic processing you'd do in CustomerService (not shown here for sake of brevity).
Does that make more sense?
Don't confuse inversion of control with dependency injection (as another answer did). I describe dependency injection and IoC here: http://www.codeproject.com/Articles/386164/Get-injected-into-the-world-of-inverted-dependenci
//dependency injection - (as was claimed)
Customer customer = new Customer(10);
IOrderDAO orderDAO = new OrderDAO();
customer.setOrderDAO(orderDAO);
customer.getOrdersByDate();
No. I would not call that DI. I would go as far as calling it badly written code. The customer should not be aware of the persistance layer which setOrderDAO(orderDAO) forces it to be. It breaks the single responsibility principle since the customer also have to take care of the orders.
//Unknown Pattern - Please what pattern is this?
Customer customer = new Customer(10);
IOrderDAO orderDAO = new OrderDAO();
orderDAO.getOrderByDate(customer.id);
It's not specific pattern, but better code since there is no coupling between the customer and the orderDao.

SerializationException: type not included in serializable type set

In my Google Web Toolkit project, I got the following error:
com.google.gwt.user.client.rpc.SerializationException: Type ‘your.class.Type’ was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.
What are the possible causes of this error?
GWT keeps track of a set of types which can be serialized and sent to the client. your.class.Type apparently was not on this list. Lists like this are stored in .gwt.rpc files. These lists are generated, so editing these lists is probably useless. How these lists are generated is a bit unclear, but you can try the following things:
Make sure your.class.Type implements java.io.Serializable
Make sure your.class.Type has a public no-args constructor
Make sure the members of your.class.Type do the same
Check if your program does not contain collections of a non-serializable type, e.g. ArrayList<Object>. If such a collection contains your.class.Type and is serialized, this error will occur.
Make your.class.Type implement IsSerializable. This marker interface was specifically meant for classes that should be sent to the client. This didn't work for me, but my class also implemented Serializable, so maybe both interfaces don't work well together.
Another option is to create a dummy class with your.class.Type as a member, and add a method to your RPC interface that gets and returns the dummy. This forces the GWT compiler to add the dummy class and its members to the serialization whitelist.
I'll also add that if you want to use a nested class, use a static member class.
I.e.,
public class Pojo {
public static class Insider {
}
}
Nonstatic member classes get the SerializationException in GWT 2.4
I had the same issue in a RemoteService like this
public List<X> getX(...);
where X is an interface. The only implementation did conform to the rules, i.e. implements Serializable or IsSerializable, has a default constructor, and all its (non-transient and non-final) fields follow those rules as well.
But I kept getting that SerializationException until I changed the result type from List to X[], so
public X[] getX(...);
worked. Interestingly, the only argument being a List, Y being an interface, was no problem at all...
I have run into this problem, and if you per chance are using JPA or Hibernate, this can be a result of trying to return the query object and not creating a new object and copying your relavant fields into that new object. Check the following out, which I saw in a google group.
#SuppressWarnings("unchecked")
public static List<Article> getForUser(User user)
{
List<Article> articles = null;
PersistenceManager pm = PMF.get().getPersistenceManager();
try
{
Query query = pm.newQuery(Article.class);
query.setFilter("email == emailParam");
query.setOrdering("timeStamp desc");
query.declareParameters("String emailParam");
List<Article> results = (List<Article>) query.execute(user.getEmail
());
articles = new ArrayList<Article>();
for (Article a : results)
{
a.getEmail();
articles.add(a);
}
}
finally
{
pm.close();
}
return articles;
}
this helped me out a lot, hopefully it points others in the right direction.
Looks like this question is very similar to what IsSerializable or not in GWT?, see more links to related documentation there.
When your class has JDO annotations, then this fixed it for me (in addition to the points in bspoel's answer) : https://stackoverflow.com/a/4826778/1099376

Injection of class with multiple constructors

Resolving a class that has multiple constructors with NInject doesn't seem to work.
public class Class1 : IClass
{
public Class1(int param) {...}
public Class1(int param2, string param3) { .. }
}
the following doesn’t seem to work:
IClass1 instance =
IocContainer.Get<IClass>(With.Parameters.ConstructorArgument(“param”, 1));
The hook in the module is simple, and worked before I added the extra constructor:
Bind().To();
The reason that it doesn't work is that manually supplied .ctor arguments are not considered in the .ctor selection process. The .ctors are scored according to how many parameters they have of which there is a binding on the parameter type. During activation, the manually supplied .ctor arguments are applied. Since you don't have bindings on int or string, they are not scored. You can force a scoring by adding the [Inject] attribute to the .ctor you wish to use.
The problem you're having is that Ninject selects .ctors based on the number of bound parameters available to it. That means that Ninject fundamentally doesn't understand overloading.
You can work around this problem by using the .ToConstructor() function in your bindings and combining it with the .Named() function. That lets you create multiple bindings for the same class to different constructors with different names. It's a little kludgy, but it works.
I maintain my own software development blog so this ended up being a post on it. If you want some example code and a little more explanation you should check it out.
http://www.nephandus.com/2013/05/10/overloading-ninject/