Nieuw lid |
|
Hallo, iedereen.
Ik ben een beginnend c# programmeur met een achtergrond in J2EE en generics.
Maar ik ben een raar probleem tegengekomen tijdens het uitproberen van nhibernate en spring.net.
Kleine schets van de situatie.
Ik werk met services om database transacties te verrichten op bepaalde objecten.
Ik heb een base interface om de CRUD acties te definieren en later geimplementeerd met Service<DomainObject>
Elke object die naar de database wordt weggeschreven extends van DomainObject
namespace DenaHibernate.Service.Interfaces
{
public interface IService<D>
where D : DomainObject
{
// create
D Create(D entity);
// read
D Read(long sid);
// update
D Update(D entity);
// delete
void Delete(D entity);
}
}
namespace DenaHibernate.Service.Interfaces { public interface IService<D> where D : DomainObject { // create D Create(D entity); // read D Read(long sid); // update D Update(D entity); // delete void Delete(D entity); } }
Als men een object UserLogin hebben dan bestaat er een een ILoginService die IService<UserLogin> gaat implementeren
De implementatie:
namespace DenaHibernate.Service.Implementation
{
public class LoginService: Service<UserLogin>, ILoginService
{
}
}
namespace DenaHibernate.Service.Implementation { public class LoginService: Service<UserLogin>, ILoginService { } }
Dus hier hebben we een basis voorbeeld van inheritance m.a.w. ILoginService is een IService<DomainObject> waar we IService<UserLogin> gaan implementeren zodat alle CRUD acties een UserLogin gaat teruggeven of verwijderen uit de database.
De declaraties van de IService<DomainObject> wordt in een xml configuratie gedefinieerd en spring.net doet de rest voor je (principe van Dependency Injection)
Om de services te kunnen gebruiken heb ik een BeanLocator aangemaakt die de gevraagde service gaat opzoeken in de xml configuratie.
BeanLocator
namespace DenaHibernate.Service.Locator
{
public class BeanLocator
{
private static IApplicationContext context;
private static BeanLocator locator;
private BeanLocator()
{
context = new XmlApplicationContext(new String[] { "~/service.xml" });
}
public static BeanLocator Instance()
{
if (locator == null)
{
locator = new BeanLocator();
}
return locator;
}
// where T : IService<DomainObject> is van belang voor de basis CRUD acties
public T getBean<T>()
where T : IService<DomainObject>
{
String beanName = typeof(T).ToString();
int lastIndex = beanName.LastIndexOf(".") + 1;
return (T)context.GetObject(beanName.Substring(lastIndex));
}
}
}
namespace DenaHibernate.Service.Locator { public class BeanLocator { private static IApplicationContext context; private static BeanLocator locator; private BeanLocator() { context = new XmlApplicationContext (new String[] { "~/service.xml" }); } public static BeanLocator Instance() { if (locator == null) { locator = new BeanLocator (); } return locator; } // where T : IService<DomainObject> is van belang voor de basis CRUD acties public T getBean<T>() where T : IService<DomainObject> { String beanName = typeof(T ). ToString(); int lastIndex = beanName.LastIndexOf(".") + 1; return (T)context.GetObject(beanName.Substring(lastIndex)); } } }
Ergens in mijn code gebruik ik de beanlocator om mijn IloginService te kunnen gebruiken.
ILoginService loginService = (ILoginService) BeanLocator.GetBean<ILoginService>();
Maar dan krijg ik een foutmelding:
Error 7 The type 'DenaHibernate.Service.Interfaces.ILoginService' cannot be used as type parameter 'T' in the generic type or method 'DenaHibernate.Manager.Management.GetService<T>()'. There is no implicit reference conversion from 'DenaHibernate.Service.Interfaces.ILoginService' to 'DenaHibernate.Service.Interfaces.IService<DenaHibernate.Domain.DomainObject>'. D:\dena\project\DenaHibernate\DenaHibernate\WebPages\EditUser.aspx.cs 40 21 DenaHibernate
Maar in dit voorbeeld is ILoginService een IService<UserLogin>
In bestaande java code die ik heb geschreven gebruik ik de zelfde programmeer benadering nml
@SuppressWarnings("unchecked")
public <S extends SwiService> S getBean(Class<S> clazz) {
return (S) context.getBean(ServiceUtilities.getSimpleClassName(clazz));
}
@SuppressWarnings("unchecked") public <S extends SwiService> S getBean(Class<S> clazz) { return (S) context.getBean(ServiceUtilities.getSimpleClassName(clazz)); }
Hier zien we dat we een SwiService gaan terug krijgen als men een SwiService class als parameter geven.
In java werkt het zoals ik het verwacht maar in C# geeft die een "casting" probleem en dat kan niet.
Ik heb het al geprobeerd om T ipv ILoginService maar dan stappelt het probleem hoger op en het is geen oplossing voor me
Graag hulp en uitleg waarom dit niet werkt.
Mvg,
Daniel Noulet
EDIT
Opgelost:
Gewoon in mijn BeanLocator de type van DomainObject meegegeven
namespace DenaHibernate.Service.Locator
{
public class BeanLocator<D>
where D : DomainObject
{
private static IApplicationContext context;
private static BeanLocator<D> locator;
private BeanLocator()
{
//context = ContextRegistry.GetContext();
context = new XmlApplicationContext(new String[] { "~/service.xml" });
}
public static BeanLocator<D> Instance()
{
if (locator == null)
{
locator = new BeanLocator<D>();
}
return locator;
}
public T getBean<T>()
where T : IService<D>
{
String beanName = typeof(T).ToString();
int lastIndex = beanName.LastIndexOf(".") + 1;
String interfaceNaam = beanName.Substring(lastIndex);
return (T)context.GetObject(interfaceNaam.Substring(1));
}
}
}
namespace DenaHibernate.Service.Locator { public class BeanLocator<D> where D : DomainObject { private static IApplicationContext context; private static BeanLocator<D> locator; private BeanLocator() { //context = ContextRegistry.GetContext(); context = new XmlApplicationContext (new String[] { "~/service.xml" }); } public static BeanLocator<D> Instance() { if (locator == null) { locator = new BeanLocator <D >(); } return locator; } public T getBean<T>() where T : IService<D> { String beanName = typeof(T ). ToString(); int lastIndex = beanName.LastIndexOf(".") + 1; String interfaceNaam = beanName.Substring(lastIndex); return (T)context.GetObject(interfaceNaam.Substring(1)); } } }
|