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.
Related
I think what I'm looking for is something very simple, yet I am unable to find any examples.
I'd like to use Ninject to create an object by having Ninject call a factory method with a parameter specified and not injected during the actual request to instantiate the object:
Request for an object here:
StandardKernel.Get<ISomeInteface>(new Ninject.Parameters.Parameter("dataContext", dataContext, true));
And I'd like to map the ISomeInterface to a method that is expecting a value to be passed to it at runtime.
Mapping an interface here:
Kernel.Bind<ISomeInterface>().ToMethod(SomeObject.Create(--> `what do I put here?`));
Is this possible? If so, how do I properly map my interface?
Thanks!
ToMethod(ctx =>
SomeObject.Create(
(IDataContext)ctx.Parameters.Single(p =>p.Name == "dataContext")
.GetValue(ctx, null))
But you should rethink your design to avoid calling Get from anywhere else than your composite root.
I have a problem using an custom data type in a WCF service method, below is my sample code
[ServiceContract()]
public class SampleServise : ISampleServise
{
void object GetSomething(ICustomData objectData)
{
// Do Something
}
}
What shall I do with ICustomData class interface?
Thanks
Afshin
WCF is based on message passing, and that message passing is modelled using XML schema (XSD). As such, whatever can be expressed in XML schema can be used in WCF.
This also means: interfaces are not supported. You need to use actual, concrete types for the parameters in your WCF service methods.
In your case, create a concrete class that implements ICustomData and then use that class as the parameter type.
For a good reference, read MSDN Designing Service Contracts which states for parameters:
Parameters and Return Values
Each operation has a return value and a parameter, even if these are
void. However, unlike a local method, in which you can pass references
to objects from one object to another, service operations do not pass
references to objects. Instead, they pass copies of the objects.
This is significant because each type used in a parameter or return
value must be serializable; that is, it must be possible to convert an
object of that type into a stream of bytes and from a stream of bytes
into an object.
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
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)
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/