Reputation: 468
I have a class LkCredentials, which is used to store data from SQL table.
[Table(Name = "Credentials")]
public class LkCredentials : LkTable
{
// Database fields
[Column(Name = "id", IsPrimaryKey = true)]
public Binary Uid { get; set; }
...
// Used for dependency injection through Ninject
public ICustomer Customer { get; set; }
public LkCredentials(ICustomer Customer)
{
this.Customer = Customer;
}
// Data loader from database
public void Load(string login)
{
var user = (new SqlTRepository<LkCredentials>()).DBObject.Where(x => x.Login == login).Single();
... // copying data from user to this
}
I'm using Ninject to inject proper ICustomer class this way:
// Create new instance for correct constructor to run and Ninject to resolve
var cred = new LkCredentials((ICustomer)null);
// Load data from database
cred.Load(model.UserName);
But in the process of loading data (void Load
), in the variable user new instance of LkCredentials is created, and compiler demands parameterless constructor to be defined. If I create parameterless constructor, then it will be used to create new instance of LkCredentials, but Ninject will not bind correct class - cause constructor incorrect :( And NullReference exception will be raised.
I tried to create constructors chain:
public LkCredentials() : this((ICustomer)null)
{ }
But it didn't work. What I can do for Ninject to work properly? Any ideas?
P.S.:
Ninject installed as MVC Extension. Ninject injection in controllers works great, with the same bindings.
Ninject bindings from NinjectWebCommon.cs:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ICustomer>().ToProvider<ObjectProvider<ICustomer, Customer, Customer82>>();
kernel.Bind<IAddress>().ToProvider<ObjectProvider<IAddress, Address, ContactInfo>>();
}
public class ObjectProvider<T1,T2,T3> : IProvider
{
public Type Type { get { return typeof(T1); } }
public object Create(IContext context)
{
var securityInfo = context.Kernel.Get<SecurityInformation>();
if (securityInfo.isAuthenticated & securityInfo.DatabaseType == "81")
return context.Kernel.Get<T2>();
else if (securityInfo.isAuthenticated & securityInfo.DatabaseType == "82")
return context.Kernel.Get<T3>();
else
return context.Kernel.Get<T2>();
}
}
Upvotes: 0
Views: 1192
Reputation: 468
I left parameterless constructor as is, but at the first point, where a need a Customer
, I added:
if (this.Customer == null)
this.Customer = (ICustomer)System.Web.Mvc.DependencyResolver.Current.GetService(typeof(ICustomer));
It was enough. Great thanks to Stephen Byrne, he gives me great advice!
Upvotes: 0
Reputation: 2058
I am a student of Ninject and like it a lot. I think the issue is you need to bind LkCredentials to an ILkCredentials and bind it with a parameter. Something like this:
Bind<ILkCredentials>().To<LkCredentials>().WithConstructorArgument("Customer", "Customer");
In the WithConstructorArgument(, ). It's a little confusing because your parameter name is also the name of the object you want to inject.
Here's another example where the parameter name is "name" and the constructor argument is "Fender":
Bind<IGuitar>().To<Guitar>().WithConstructorArgument("name", "Fender");
Hope that helps.
Upvotes: 0