waoywssy / linfu

Automatically exported from code.google.com/p/linfu
0 stars 0 forks source link

DoGetInstance with generic type arguments (ServiceLocator) #43

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?

1. Register a Service for a generic type, like IRepository<>
2. Use ServiceLocator to locate a service for IRepository<ConcreteObject>
3. DoGetInstance will throw a NullReferenceException

What is the expected output? What do you see instead?

DoGetInstance should return a concrete Repository<ConcreteObject>.

LinFu.IoC is clever enough to solve this problem, but the functor in 
DoGetInstance will only check whether the type you want to get an instance 
for is exactly the same (and IRepository<> != IRepository<x>). 

One solution would be to add a check at the end of the DoGetInstance so it 
would run the bare IoC.GetService without any specific argument, because 
LinFu is clever enough to figure out what you actualy need:

var defaultService = 
_container.AvailableServices.Where(criteria).FirstOrDefault();
if (defaultService != null)
{
  // If we found the type use that service
  return _container.GetService(defaultService);
}
else
{
  // If not, let LinFu.IoC figure out what I want
  return _container.GetService(serviceType);
}

Of course a better solution would be to check for registered services which 
have the generic types we need, and use the appropriate getservice call.

DoGetAllInstances should be fixed as well

Original issue reported on code.google.com by szt...@gmail.com on 28 Apr 2010 at 7:12

GoogleCodeExporter commented 9 years ago
Unfortunately, I wasn't able to reproduce the bug, but I did add the following 
tests 
that verify that the bug doesn't actually exist:

[Test]
        public void 
ContainerShouldBeAbleToRegisterGenericTypeAndResolveConcreteServiceType()
        {
            var container = new ServiceContainer();
            container.AddService(typeof(ISampleGenericService<>), 
typeof(SampleGenericClassWithOpenGenericImplementation<>));

            var instance = container.GetService<ISampleGenericService<int>>();
            Assert.IsNotNull(instance);
        }

        [Test]
        public void 
ContainerShouldBeAbleToRegisterGenericTypeAndResolveConcreteServiceTypeUsingTheN
onGen
ericGetServiceMethod() 
        {
            var container = new ServiceContainer();
            container.AddService(typeof(ISampleGenericService<>), 
typeof(SampleGenericClassWithOpenGenericImplementation<>));

            var instance = container.GetService(typeof(ISampleGenericService<int>));
            Assert.IsNotNull(instance);
        }

Both of these tests passed, and you can find them in 
InversionOfControlTests.cs. The 
latest version of LinFu.IOC v2.0 can be found in the Github repository using 
the 
following link:

http://github.com/philiplaureano/LinFu

Try it out and let me know if it helps. 

Regards,

Philip Laureano

Original comment by Philip.L...@gmail.com on 28 Apr 2010 at 10:43

GoogleCodeExporter commented 9 years ago
I took a look at the bug again and I managed to reproduce it with the Linfu CSL 
adapter, but the problem is that modifying the adapter to support resolving 
concrete 
generic instantiations from generic service types would be non-standard 
behavior for 
the CSL adapters.

In other words, not all the other containers are capable of doing what LinFu 
does 
with generics, and while LinFu itself can easily handle the behavior that you 
mentioned, it needs to conform to the Common Service Locator spec, so 
unfortunately, 
I won't be able to fix this without breaking the CSL implementation.

Original comment by Philip.L...@gmail.com on 28 Apr 2010 at 11:25

GoogleCodeExporter commented 9 years ago
Where can I find these specs? The CSL page says "The project contains a full 
test 
suite", which I couldn't find, the API reference says nothing about generic 
types (it 
only says the container should return a type that implements the requested 
interface), 
and other adapters (like the Castle.Windsor based one) doesn't seem to care 
either.

Original comment by szt...@gmail.com on 29 Apr 2010 at 7:34