How do I register default interfaces with Castle Windsor given an interface ancestor? - castle-windsor-3

I have the following:
interface IAncestor { }
interface IDescendant1 : IAncestor { }
interface IDescendant2 : IAncestor { }
class Descendant1 : IDescendant1 { }
class Descendant2 : IDescendant2 { }
What I would like to be able to do is automatically have Castle Windsor find all IDescendantX-DescendantX pairs without me having to specify them manually. Is this possible?
I've tried:
container.Register(
Classes.FromThisAssembly()
.BasedOn<IAncestor>()
.WithService.DefaultInterfaces()
.LifestyleTransient()
);
but this does not find the default interfaces. (I'm having trouble phrasing my question with the right terminology, so could not find a topic on SO that already answers this, sorry if it's a duplicate...)

Think the problem here is lack of access modifiers. If you add IncludeNonPublicTypes() the following test passes:
[Test]
public void Test()
{
//Arrange
WindsorContainer sut = new WindsorContainer();
//Act
sut.Register(
Classes.FromThisAssembly()
.IncludeNonPublicTypes()
.BasedOn<IAncestor>()
.WithService.DefaultInterfaces()
.LifestyleTransient());
//Assert
Assert.That(sut.Resolve<IDescendant1>(), Is.InstanceOf<Descendant1>());
Assert.That(sut.Resolve<IDescendant2>(), Is.InstanceOf<Descendant2>());
}

Related

Possible to register NullObject implementation as a fallback for a generic interface?

We use a lot of Generics in our code. For example ICommandHandler<T> where T is ICommand, ICommandValidator<T> etc etc
Not everything has a ICommandValidator implementation. I was looking to use the NullObject pattern so that I could provide a fall back option to avoid having to test if validator is null.
For example
public class NullObjectCommandValidator : ICommandValidator<ICommand>
{
public bool IsValid(ICommand command)
{
return true;
}
}
We register all like:
builder.RegisterAssemblyTypes(assemblies)
.AsClosedTypesOf(typeof(ICommandValidator<>))
.InstancePerHttpRequest();
I was hoping to be able to register the NullObjectCommandValidator as a default for any ICommandValidator that didn't have a concrete implementation using a process like registering all other ICommandValidators<> and then registering the Null version at the end and preserving existing defaults.
Is something like this possible?
You should change NullObjectCommandValidator to a generic type NullObjectCommandValidator<TCommand>. This way you can register it as follows:
builder.RegisterGeneric(typeof(NullObjectCommandValidator<>))
.As(typeof(ICommandValidator<>));
NullObjectCommandValidator<TCommand> looks like this:
public class NullObjectCommandValidator<TCommand> : ICommandValidator<TCommand>
{
public bool IsValid(TCommand command)
{
return true;
}
}

running a T4 on adding a class

Using t4, I want when the developer adds a class which ends to Report keyword (e.g. CompanyReport), put some code in that class.
Imagine I create a class named CompanyReport, I want the class to be like :
public class CompanyReport : IReportItem
{
private Company _company;
public CompanyReport(Company company)
{
_company = company;
}
public ReportBookmark BookMark
{
get { return ReportBookmark.Company; }
}
public void Report(ISetBookmark wordReport)
{
}
}
Maybe you should consider using a customized ItemTemplate for Visual Studio or just a snippet. Both are quite easy to build and redistribute. I'am also not sure if it is possible to invoke some T4-Template on creating (and really ONLY on creating) a class.

How to dynamically create collections of derived objects?

This question may appear to have been answered before but I have been unable to find exactly what I need. Here is my situation:
// Base class
interface IAnimal {};
public abstract class Animal : IAnimal{}
// Derived classes
interface IDog {}
public class Dog : Animal, IDog { }
interface ICat { }
public class Cat : Animal, ICat { }
interface ITiger { }
public class Tiger : Animal, ITiger { }
interface ILion { }
public class Lion : Animal, ILion { }
// Collection Classes
interface IPets { }
public class Pets
{
IDog dog = new Dog();
ICat cat = new Cat();
}
interface ICircus { }
public class Circus
{
ITiger tiger = new Tiger();
ILion lion = new Lion();
}
I would like to create the collections at run time in an generic Event class by reading in a list animals from xml that would make up the collection. What would be the correct way to accomplish this?
Thanks in advance.
This is kind of an answer to my own question. Maybe this will help others.
I chose a very generic example to illustrate my situation because I have uses for this in many places in Windows Forms, XNA and Silverlight that are all very different.
When I used the Activator, I found out that it assumes the executing assembly. My method is in a library so I had to load a different assembly. Next I had to make sure that I had the right namespace. My base class is in a library and the derived classes are in another namespace so this will require refactoring to properly create the list.
Another problem I found was that the Activator assumes a constructor with no parameters. In my test case all my derived classes are XNA game components with a parameter of type Game.
Have to do some refactoring to test out the interfaces and how the game objects are to interact.
Will be back to this list when I have something further.
Does this sort of example help? (It's from some of my code I happened to have handy.) The key point here is the use of reflection in Activator.CreateInstance(...).
public static List<dynamic> LoadChildEntities(XElement entityElt)
{
var children = new List<dynamic>();
foreach(XElement childElt in entityElt.Elements("entity"))
{
// Look up the C# type of the child entity.
string childTypename = "MyNamespace." + Convert.ToString(childElt.Attribute("type").Value);
Type childType = Type.GetType(childTypename);
if(childType != null)
{
// Construct the child entity and add it to the list.
children.Add(Activator.CreateInstance(childType, childElt));
}
else
{
throw new InvalidOperationException("No such class: " + childTypename);
}
}
return children;
}
If you want a list of IAnimal instead, it wouldn't be too tricky to change.

How to provide injection for method which is called in NinjectModule

I have the following NinjectModule derived class:
class MainModule : NinjectModule
{
public override void Load()
{
Bind<IMyClass>().To<MyClass>();
Bind<IMainClass>().To<MainClass>().OnActivation((context,myClass) =>
{ myClass.Add("Something", context.Kernel.Get<IMyClass>()); });
}
}
My problem is that IKernel does not exposed the .Get<T> extension method.
Is there a pattern for doing this?
Caveats: I don't want to have to decorate my classes with Ninject attributes, as the Add is specific to how MainClass works I wanted all the code to do with its creation to be held in this module.
TIA
Hmmm, silly oversight in the end it seems. The extension methods reside in the Ninject namespace, using a module only requires that you are using Ninject.Modules;
Adding using Ninject; meant that the following was possible:
Bind<IMainClass>().To<MainClass>()
.OnActivation((context,myClass) =>
{
foreach(var n in context.Kernel.GetAll<IMyClass>())
{
myClass.Add("Something", n);
}
});
I'll leave this open for a bit to see if anyone has a better way of doing this.

looking for a proper way to implement my generic factory

I'm struggling with implementing a factory object. Here's the context :
I've in a project a custom store. In order to read/write records, I've written this code in a POCO model/separated repository:
public class Id { /* skip for clarity*/} // My custom ID representation
public interface IId
{
Id Id { get; set; }
}
public interface IGenericRepository<T> where T : IId
{
T Get(Id objectID);
void Save(T #object);
}
public interface IContext
{
TRepository GetRepository<T, TRepository>()
where TRepository : IGenericRepository<T>
where T:IId;
IGenericRepository<T> GetRepository<T>()
where T:IId;
}
My IContext interface defines two kind of repositories.
The former is for standard objects with only get/save methods, the later allows me to define specifics methods for specific kind of objects. For example :
public interface IWebServiceLogRepository : IGenericRepository<WebServiceLog>
{
ICollection<WebServiceLog> GetOpenLogs(Id objectID);
}
And it the consuming code I can do one of this :
MyContext.GetRepository<Customer>().Get(myID); --> standard get
MyContext.GetRepository<WebServiceLog, IWebServiceLogRepository>().GetOpenLogs(myID); --> specific operation
Because most of objects repository are limited to get and save operations, I've written a generic repository :
public class BaseRepository<T> : IGenericRepository<T>
where T : IId, new()
{
public virtual T Get(Id objectID){ /* provider specific */ }
public void Save(T #object) { /* provider specific */ }
}
and, for custom ones, I simply inherits the base repository :
internal class WebServiceLogRepository: BaseRepository<WebServiceLog>, IWebServiceLogRepository
{
public ICollection<WebServiceLog> GetByOpenLogsByRecordID(Id objectID)
{
/* provider specific */
}
}
Everything above is ok (at least I think it's ok). I'm now struggling to implement the MyContext class. I'm using MEF in my project for other purposes. But because MEF doesn't support (yet) generic exports, I did not find a way to reach my goal.
My context class is looking like by now :
[Export(typeof(IContext))]
public class UpdateContext : IContext
{
private System.Collections.Generic.Dictionary<Type, object> m_Implementations;
public UpdateContext()
{
m_Implementations = new System.Collections.Generic.Dictionary<Type, object>();
}
public TRepository GetRepository<T, TRepository>()
where T : IId
where TRepository : IGenericRepository<T>
{
var tType = typeof(T);
if (!m_Implementations.ContainsKey(tType))
{
/* this code is neither working nor elegant for me */
var resultType = AppDomain.CurrentDomain.GetAssemblies().SelectMany(
(a) => a.GetTypes()
).Where((t)=>t.GetInterfaces().Contains(typeof(TRepository))).Single();
var result = (TRepository)resultType.InvokeMember("new", System.Reflection.BindingFlags.CreateInstance, null, null, new object[] { this });
m_Implementations.Add(tType, result);
}
return (TRepository)m_Implementations[tType];
}
public IGenericRepository<T> GetRepository<T>() where T : IId
{
return GetRepository<T, IGenericRepository<T>>();
}
}
I'd appreciate a bit of help to unpuzzle my mind with this quite common scenario
Not sure if I've understood you correctly, but I think you're perhaps over complicating things. To begin with, make sure you've designed your code independent of any factory or Dependency Injection framework or composition framework.
For starters lets look at what you want your calling code to look like, this is what you said:
MyContext.GetRepository<Customer>().Get(myID); --> standard get
MyContext.GetRepository<WebServiceLog, IWebServiceLogRepository>().GetOpenLogs(myID);
You don't have to agree with my naming choices below, but it indicates what I undertand from your code, you can tell me if I'm wrong. Now, I feel like the calling would be simpler like this:
RepositoryFactory.New<IRepository<Customer>>().Get(myId);
RepositoryFactory.New<IWebServiceLogRepository>().GetOpenLogs(myId);
Line 1:
Because the type here is IRepository it's clear what the return type is, and what the T type is for the base IRepository.
Line 2:
The return type here from the factory is IWebServiceLogRepository. Here you don'y need to specify the entity type, your interface logically already implements IRepository. There's no need to specify this again.
So your interface for these would look like this:
public interface IRepository<T>
{
T Get(object Id);
T Save(T object);
}
public interface IWebServiceLogRepository: IRepository<WebServiceLog>
{
List<WebServiceLog> GetOpenLogs(object Id);
}
Now I think the implementations and factory code for this would be simpler as the factory only has to know about a single type. On line 1 the type is IRepository, and in line 2, IWebServiceLogRepository.
Try that, and try rewriting your code to simply find classes that implement those types and instantiating them.
Lastly, in terms of MEF, you could carry on using that, but Castle Windsor would really make things much simpler for you, as it lets you concentrate on your architecture and code design, and its very very simple to use. You only ever reference Castle in your app startup code. The rest of your code is simply designed using the Dependency Injection pattern, which is framework agnostic.
If some of this isn't clear, let me know if you'd like me to update this answer with the implementation code of your repositories too.
UPDATE
and here's the code which resolves the implementations. You were making it a bit harder for yourself by not using the Activator class.
If you use Activator and use only one Generic parameter as I've done in the method below, you should be ok. Note the code's a bit rough but you get the idea:
public static T GetThing<T>()
{
List<Type> assemblyTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes()).ToList();
Type interfaceType = typeof(T);
if(interfaceType.IsGenericType)
{
var gens = interfaceType.GetGenericArguments();
List<Type> narrowed = assemblyTypes.Where(p => p.IsGenericType && !p.IsInterface).ToList();
var implementations = new List<Type>();
narrowed.ForEach(t=>
{
try
{
var imp = t.MakeGenericType(gens);
if(interfaceType.IsAssignableFrom(imp))
{
implementations.Add(imp);
}
}catch
{
}
});
return (T)Activator.CreateInstance(implementations.First());
}
else
{
List<Type> implementations = assemblyTypes.Where(p => interfaceType.IsAssignableFrom(p) && !p.IsInterface).ToList();
return (T)Activator.CreateInstance(implementations.First());
}
}

Resources