LightInject - Derived interfaces leads to multiple instances - c#

In my application I handle lots of ViewModels that get registered inside a LightInject Container via several Interfaces. Some of those Interfaces are derived from other for UnitTesting purposes.
When resolving multiple ViewModels with the same Interface that is an interface further above I get more ViewModelinstances than expected.
I made a simplified example for this behavior. Is it possible to prevent this behavior somehow?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
public interface IBar
{
}
public interface IFoo : IBar
{
}
public class Cat : IFoo
{
}
class Program
{
static void Main(string[] args)
{
var container = new LightInject.ServiceContainer();
container.Register<IBar, Cat>();
container.Register<IFoo, Cat>();
var m = container.GetAllInstances(typeof(IBar));
// m will contain 2 Instances of Cat. Is it possible it will resolve only 1 Instance?
}
}
}

Try this
var container = new ServiceContainer(new ContainerOptions() {EnableVariance = false});

Related

System.web.Mvc DependencyResolver not able to create object for generic classes

I am trying to use dependencyinjection in Controller and using
System.Web.MvcDependencyResolver.Current.GetService() for creating service instances in controller class.
This works fine when Service Interfaces are non generic as below
public interface IProfileManagementService
{
IList<News> GetSavedSearchList(int userObjectId, ApplicationType applicationType,int? vendorUserObjectId);
}
and my dependency resolver syntax as below gives me instance of ProfileManagementService
DependencyResolver.Current.GetService<IProfileManagementService>();
But If I create any generic service interface as below,
public interface ICommonProfileManagementService<T>
{
IList<T> GetSavedSearchList(int userObjectId, ApplicationType applicationType,int? vendorUserObjectId);
}
But I get a null (CommonProfileManagementService objects are not created) for below code
DependencyResolver.Current.GetService<ICommonProfileManagementService<News>>();
Please Suggest some alternate ways of passing
IService<T>
instead of
IService
to DependencyResolver.Current.GetService()
Here is the full code including the syntax needed to return a generic from DependencyResolver.
using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Microsoft.Practices.Unity.Mvc;
namespace ConsoleApplication2
{
class Program
{
public interface IService<T>
{
List<T> GetService();
}
public class Service<T> : IService<T>
{
public List<T> GetService()
{
return new List<T>();
}
}
static void Main(string[] args)
{
var container = new UnityContainer();
container.RegisterType(typeof(IService<>), typeof(Service<>));
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
var service = DependencyResolver.Current.GetService(typeof(IService<string>));
Console.WriteLine(service.ToString());
Console.ReadKey();
}
}
}

Replacing registered type in Unity RegisterType<TFrom, TTo> vs ReigsterType<T>

The scenario that I currently have is that I am writing a unit test for some code that uses another library of code that uses dependency injection and provides a UnitContainerExtension to bootstrap all the concrete classes required by the library. However in my unit test I want to be able to mock one or two the registered types. Now in theory according to all the post I could see there should be no issue with registering and then re-registering a type. The latter definition / mapping replacing the former.
However this does not seem to work in practice. Now I could just copy the list of type registration from the libraries extension and ommit / change the ones I need to mock. However I thought that this doesn't seem right and maybe I am missing something.
The following is an example of the code (which has been simplified and had the UnitContainerExtension inlined) :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using Moq;
namespace UnityTest
{
class Program
{
private static IFooBar _mockFooBar;
public static IFooBar MockFooBar
{
get
{
return _mockFooBar ?? (_mockFooBar = Mock.Of<IFooBar>(fb => fb.Test(It.IsAny<string>()) == "I am mockery of FooBar!"));
}
}
static void Main(string[] args)
{
UnityContainer container = new UnityContainer();
//Registration of concrete class done inside extension
container.RegisterType<IFooBar, FooBar>();
//Re-registering
container.RegisterType<IFooBar>(new InjectionFactory(uc => MockFooBar));
//This should resolve to the mocked foobar but doesn't
Console.WriteLine(container.Resolve<IFooBar>().Test("I am the concrete FooBar!"));
Console.ReadLine();
}
public interface IFooBar
{
string Test(string text);
}
public class FooBar : IFooBar
{
public string Test(string text)
{
// Some concrete code
return text;
}
}
}
}
However the IFooBar type resolves to the concrete FooBar class instead of the Mocked version.
I suspect that calling RegesterType <T> instead of RegisterType<TFrom, TTo> when re-registering might be the issue.
The following is a screen shot of the container at runtime after the second call to RegisterType:
Also the same seems to occur using another 'non mocked' class, which is not that surprising as hopefully Unity isn't looking at the type of the mapped to object.
Using the following amended example source:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using Moq;
namespace UnityTest
{
class Program
{
private static IFooBar _mockFooBar;
public static IFooBar MockFooBar
{
get
{
return _mockFooBar ?? (_mockFooBar = Mock.Of<IFooBar>(fb => fb.Test(It.IsAny<string>()) == "I am mockery of FooBar!"));
}
}
static void Main(string[] args)
{
UnityContainer container = new UnityContainer();
//Registration of concrete class done inside extension
container.RegisterType<IFooBar, FooBar>();
//Re-registering
container.RegisterType<IFooBar>(new InjectionFactory(uc => MockFooBar));
//Re-registering
container.RegisterType<IFooBar>(new InjectionFactory(uc => new FooBar2()));
//This should resolve to the mocked foobar but doesn't
Console.WriteLine(container.Resolve<IFooBar>().Test("I am the original FooBar!"));
Console.ReadLine();
}
public interface IFooBar
{
string Test(string text);
}
public class FooBar : IFooBar
{
public string Test(string text)
{
// Some concrete code
return text;
}
}
public class FooBar2 : IFooBar
{
public string Test(string text)
{
// Some concrete code
return "FooBar 2.0";
}
}
}
}
Gives the same results - that is the first registration is used over any of the subsequent ones:
I would say this counts as a bug in Unity but if you already registered the interface to a concrete type, the overwriting registration has to contain a concrete type even though the factory method is used.
In your example:
container.RegisterType<IFooBar, FooBar>();
//Re-registering
container.RegisterType<IFooBar, FooBar>(new InjectionFactory(uc => MockFooBar));
I verified that the type in your overwriting registration could be any concrete type implementing the interface.

How to derive a class from a nested interface?

The following code is not compilable:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args) { }
}
class Class : Class.Interface
{
internal interface Interface
{
}
}
}
The error message is:
error CS0146: Circular base class dependency involving 'ConsoleApplication1.Class' and 'ConsoleApplication1.Class.Interface'
Don't understand this.
Update:
This is probably more "motivating" (-;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args) { }
}
class Container : Container.Interface
{
// Everything, that is of type "Container.Interface" can be used as child here.
// ... including the container itself.
Interface[] _children;
// Is nested to keep the naming consistent.
internal interface Interface
{}
}
}
Wenn I put the interface outside of class "Container", it should be named somthing like "ContainerChildInterface". In my project I will have several classes like this, and thus several interfaces. And I think, using nested interfaces would be much better style in this case.

How to change a target using Castle DynamicProxy

I am trying to understand Castle's DynamicProxy and the thing I would like to do is to change the target of the generated proxy at runtime.
Something like this...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Castle.DynamicProxy;
namespace ConsoleApplication16
{
class Program
{
static void Main(string[] args)
{
IFoo foo = new Foo("Foo 1");
IFoo foo2 = new Foo("Foo 2");
foo.DoSomething("Hello!");
ProxyGenerator generator = new ProxyGenerator();
IFoo proxiedFoo = generator.CreateInterfaceProxyWithTarget<IFoo>(foo);
proxiedFoo.DoSomething("Hello proxied!");
(proxiedFoo as IChangeProxyTarget).ChangeProxyTarget(foo2); // cast results in null reference
proxiedFoo.DoSomething("Hello!");
}
}
}
I thought the generated proxy would implement IChangeProxyTarget but the cast to the interface results in a null reference.
How can I change the target of a generated proxy at runtime?
Update As mentioned in an answer, I tried using CreateInterfaceProxyWithTargetInterface and I'm still unable to cast to IChangeProxyTarget to change the target.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Castle.DynamicProxy;
namespace ConsoleApplication16
{
class Program
{
static void Main(string[] args)
{
IFoo foo = new Foo("Foo 1");
IFoo foo2 = new Foo("Foo 2");
foo.DoSomething("Hello!");
ProxyGenerator generator = new ProxyGenerator();
IFoo proxiedFoo = generator.CreateInterfaceProxyWithTargetInterface<IFoo>(foo);
proxiedFoo.DoSomething("Hello proxied!");
IChangeProxyTarget changeProxyTarget = proxiedFoo as IChangeProxyTarget;
if (changeProxyTarget == null) // always null...
{
Console.WriteLine("Failed");
return;
}
changeProxyTarget.ChangeProxyTarget(foo2);
proxiedFoo.DoSomething("Hello!");
}
}
}
use CreateInterfaceProxyWithTargetInterface
That one will allow you to change the proxy/invocation target.
Also the IChangeProxyTarget is implemented by invocation type, not the proxy itself.

TypedParameter is not used if the type is already register

I have an unexpected behavior of the TypedParameter in Autofac. It ignored if the type is already register and I don't know if is it correct or how to obtain the expected behavior. Example:
I have a Foo class with the following constructor.
public class Foo
{
public Foo(IEnumerable<IRule> rules)
{..}
}
I've already register a lot of rules inside the builder (scanning the assembly), but when I resolve, I would like to pass an Autofac TypedParameter with a custom list of IRules
TypedParameter iocParam = new TypedParameter(typeof(IEnumerable<IRule>), rules);
var result = container.Resolve(FOO, iocParam);
The problem here is Autofac is ignoring myCustomListOfRules and creating a list with all available IRules already register in first place, instead of using the TypedParameter.
If I use a NamedParameter:
NamedParameter iocParam = new NamedParameter("rules", myCustomListOfRules);
works fine, but I have to hardcode the name of the parameter instead of resolve it by the type.
Is it correct the behavior of the TypedParameter or there is a way to use it as I want?
Update:
I was doing something else bad because the TypedParameter has the expected behavior. The following example works as expected.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autofac;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<Rule1>().As<IRule>();
builder.RegisterType<Rule2>().As<IRule>();
builder.RegisterType<Foo>();
var resolver=builder.Build();
// autofac resolve foo with all of available rules, ok¡
var foo1=resolver.Resolve<Foo>();
Console.WriteLine(foo1.GetNumberOfRules());
// resolve with custom rules, ok¡
var rules=new List<IRule>();
rules.Add(new Rule1());
TypedParameter param = new TypedParameter(typeof(IEnumerable<IRule>), rules);
var foo2 = resolver.Resolve<Foo>(param);
Console.WriteLine(foo2.GetNumberOfRules());
Console.ReadLine();
}
}
public class Foo
{
IEnumerable<IRule> rules;
public Foo(IEnumerable<IRule> rules)
{
this.rules = rules;
}
public int GetNumberOfRules()
{
return this.rules.Count();
}
}
public interface IRule
{
}
public class Rule1 : IRule
{
}
public class Rule2 : IRule
{
}
}

Categories

Resources