ninject ioc with inherited base generic repository - ioc-container

I have a generic repository, abstract and concrete as below
public interface IGenericRepository<T> where T : class
public class GenericRepository<T> : IGenericRepository<T> where T : class
I then have an repository that inherits from this, again abstract and concrete
public interface ISkyDiveCentreRepository : IGenericRepository<DiveCentre>
public class SkyDiveCentreRepository : GenericRepository<DiveCentre>
In my ninject config I then have
kernel.Bind(typeof(IGenericRepository<>)).To(typeof(GenericRepository<>));
kernel.Bind<ISkyDiveCentreRepository>().To<SkyDiveCentreRepository>();
This is the first time I've tried to do this but am getting the error:
Error 2 The type 'UKSkyDiveCentres.DAL.imp.SkyDiveCentreRepository' cannot be used as type parameter 'TImplementation' in the generic type or method 'Ninject.Syntax.IBindingToSyntax<T1>.To<TImplementation>()'. There is no implicit reference conversion from 'SkyDiveCentres.DAL.imp.SkyDiveCentreRepository' to 'SkyDiveCentres.DAL.ISkyDiveCentreRepository'. C:SOMEPATH\UKSkyDiveCentres\App_Start\NinjectWebCommon.cs 56 13 SkyDiveCentres

Your SkyDiveCentreRepository inherits from GenericRepository<DiveCentre> and doesn't implement the ISkyDiveCentreRepository interface.
Simply explicitly implement it:
public class SkyDiveCentreRepository :
GenericRepository<DiveCentre>, ISkyDiveCentreRepository
// ^^^^^^^^^^^^^^^^^^^^^^^^ this
Without it.. you can't do simple things like this:
ISkyDiveCentreRepository repo = new SkyDiveCentreRepository();
If you can't do it.. Ninject can't either.

Related

Can razorpages have a common base class beside pagemodel?

Can I create a base class to use for several razorpages, as long as the base class inherits from PageModel? I have not seen any examples using this approach, but it would seem like a good way to setup dependencies that need to be injected. Rather than inject on each page model constructor, do it once in the base.
You can't inherit from multiple classes, c# allows inheriting from only one base class. But you still able to implement multiple interfaces beside the base PageModel.
As a workaround, your base class can inherit from another base class that has PageModel as base class and so on... but try not to avoid the kiss principle (see Programming principles)
public class MyBasePageModel : PageModel
{
// custom implementations...
}
Then apply to IndexModel:
public class IndexModel : MyBasePageModel
{
// ...
}

c# how to select test or prod class from config file

I have built a cloud project for a month. My problem is that:
I have 2 classes to connect with Ibm web service. First class is the main class and the second one is test class. I put a key-value to appSetting in Config File.
If value in configFile is "TEST", the project will use test class and if value is the "PROD", the project will use main class. When I change the value in config, I will not change everywhere.
My Manager gave me advice to use "interface" but I didn't understand.
How can I solve this problem basiclly?
Both your test class and prod class could implement the said interface. If you need to use the approach where you do the selection in the config file of which class to use you are probably better off creating a data factory class that returns the correct implementation of the interface. The data factory reads the config file and depending on the value in app settings returns the correct class that implements the interface.
Example of doing this in C# (the concept is the same in other oo languages as well):
From the calling class:
SomethingFactory factory = new SomethingFactory();
ISomething testOrProdObj = factory.GetCorrectImplementation();
var result = testOrProdObj.MyMethod();
And in the factory class:
public class SomethingFactory
{
public ISomething GetCorrectImplementation()
{
//Do a check in appsettings to decide which class (TESTSomething or PRODSomething) to instantiate and return
}
}
Implementation of the interface
public class TESTSomething : ISomething
or
public class PRODSomething : ISomething

Mapping inheritance in NHibernate 3.3

I have the inheritance described below :
public abstract class BaseEntity<TId> {....}
public abstract class ModelEntity : BaseEntity<Int32>{....}
public abstract class AuditableEntity : ModelEntity,IAuditable{....}
public class ApplicationUser : AuditableEntity{....}
public class SuperUser : ApplicationUser
I am using NHibernate 3.3 and I want to Create the mappings for that inheritance
public abstract class ModelEntityMap<TEntity> : ClassMapping<TEntity>
where TEntity : ModelEntity
{...}
public class AuditableEntityMap<TEntity> : ModelEntityMap<TEntity> where TEntity : AuditableEntity
{ ...}
public class ApplicationUserMap : AuditableEntityMap<ApplicationUser>
{...}
public class SuperUserMap : JoinedSubclassMapping<SuperUser>{...}
When the application starts and trys to set up the database it raises the following Exception :
Ambiguous mapping for SuperUser More than one root entities was found BaseEntity / ApplicationUser
Possible solutions
-Merge the mapping of root Entity in the one is representing the real root in the hierarchy
-Inject a IModelInspector with a logic to discover the real root-entity.
I was using Fluent nhibernate with the same inheritance and worked fine with SuperUserMap defined as
public class SuperUserMap : SubClassMap {...}
I am new to Nhibernate mapping by code and quite confused !!!
I believe there are two ways to solve this problem:
a) Using the concept of discriminator that identifies the type of the class stored and thereby the right object is retrieved from the database, in this case your class is mapped to a table that has all the columns plus the discriminator columns. Not sure how this works with multi-level inheritance but this is something that you can google.
b) take a look at this post on how he deals with inheritance: http://fabiomaulo.blogspot.co.nz/2011/04/nhibernate-32-mapping-by-code_13.html you might get some idea to solve your issue.
You can influence the decision whether an entity is a root entity by overriding the IsRootEntity logic of the model mapper that you use to create mappings.
Here's an example that defines the default NHibernate mapping-by-code behaviour:
var modelMapper = new ConventionModelMapper();
modelMapper.IsRootEntity((type, declared) =>
{
if (declared) return true; // Type has already been declared as root entity
return type.IsClass
&& typeof(object) == type.BaseType
&& modelMapper.ModelInspector.IsEntity(type);
});
You will have to tweak this decision logic to exclude the BaseEntity class as possible root entity.
I had this error with NHibernate 4.1.1 (May 2017), so I'm answering with how I solved it for future reference
In my case, I copied an existing mapping of an inheriting class, and forgot to change the parent mapping class to ClassMapping and encountered the same error
In other words, in your mapping class, check the parent class, make sure it is ClassMapping or JoinedSubclassMapping if it's a child class

Does an inherited class automatically implement an Interface from its base class?

Suppose I have piece of code like this:
Public Interface ISomething
....
End Interface
Public Class SomeClass
Implements ISomething
....
End Class
Now, if I inherit from SomeClass like this:
Public Class InheritedClass
Inherits SomeClass
....
End Class
will InheritedClass automatically implements ISomething, or must I use Implements ISomething in the InheritedClass' definition?
The interface was already implemented by the base class. Your derived class will thus implement it as well since it inherits the base class implementation. If you want to alter the base class implementation then you should declare the implementation method(s) virtual so you can override them.
Yes, the interface will be inherited as well.

How to make my class implement from IMyInterface<T>?

I want to port the following code from c# to c++/cli:
class MyClass : IEnumerable<int> { ... }
I've tried
class ref class MyClass : IEnumerable<int>
but it doesn't seem to be working.
C++ has multiple types of inheritance. Don't forget to specify it, e.g.:
ref class MyClass : public IEnumerable<int>
{ };
In C++/CLI, I frequently find myself spelling out the full namespace in interface implementations. E.g.:
ref class MyClass :
public MyCompany::MyProject::MyComponent::IMyInterface
{ };
If your class doesn't actually implement the provided interface, you'll also (of course) get an error. And you'll want to remove the ^ from the class declaration. You're inheriting from an interface, not from a GC Handle to an instance of that interface.
Assuming your code is exactly what you're trying to compile, you have an extra class there. It should be just ref class, and not class ref class. Also, don't forget to translate any C# using statements to C++ using namespace, i.e.: using namespace System::Collections::Generic.