Reputation: 8343
Though I've used generics in Castle Windsor before, this particular combination has currently got me stumped.
I'd like to resolve it as a constructor argument, which is simulated in this unit test by explicitly calling resolve().
But I cannot figure out what combination of registration and resolving I need to do. I show the code with a failing test, below, to make the problem clear.
public abstract class BaseSettings<T> where T : class
{
protected void Save(T obj)
{ }
}
public class AddinSettings : BaseSettings<AddinSettings>
{ }
public class OtherSettings : BaseSettings<OtherSettings>
{ }
public class LogConfig<T> where T : class
{
private readonly BaseSettings<T> _client;
public LogConfig(BaseSettings<T> client)
{
_client = client;
}
public BaseSettings<T> Client
{
get { return _client; }
}
}
[Test]
public void resolve_generics()
{
var container = new WindsorContainer();
container.Register(Component.For<OtherSettings >());
var otherSettings = container.Resolve<LogConfig<OtherSettings>>();
Assert.That(otherSettings, Is.Not.Null);
}
Upvotes: 0
Views: 555
Reputation: 15737
First, it is needed to register an open generic type LogConfig<>
as @Marwijn did.
Then, you can register all BaseSettings<T>
implementations by means of selecting base type/condition and service for the component using BasedOn(typeof(BaseSettings<>))
and WithService.Base()
.
The following test method proves it:
[TestMethod]
public void resolve_generics()
{
// arrange
var container = new WindsorContainer();
container.Register(
Component.For(typeof(LogConfig<>)),
Classes.FromThisAssembly().BasedOn(typeof(BaseSettings<>)).WithService.Base());
//act
var otherSettings = container.Resolve<LogConfig<OtherSettings>>();
var addinSettings = container.Resolve<LogConfig<AddinSettings>>();
// assert
otherSettings.Should().NotBeNull();
otherSettings.Client.Should().BeOfType<OtherSettings>();
addinSettings.Should().NotBeNull();
addinSettings.Client.Should().BeOfType<AddinSettings>();
}
There is another answer on the similar question about registering types based on base class.
Upvotes: 3
Reputation: 1681
You can try this:
container.Register(
Component.For(typeof(LogConfig<>)),
Component.For<BaseSettings<OtherSettings>>().ImplementedBy<OtherSettings>());
Goodluck, Marwijn.
Upvotes: 0