Windsor Castle IoC, how to register IBaseService<TObject> to BaseService<TObject, TRepository> - inversion-of-control

I have something like this:
public interface IBaseService<TObject>
public class BaseService<TObject, TRepository> : IBaseService<TObject>
where TRepository : IRepository<TObject>
I need to register BaseService To IBaseService
(the IRepository<> is registered)

if you have to do it like this you'd have to override DefaultKernel.BuildCreationContext (or something like that).
Generally what you're doing is not supported because it's wrong and vague. You're better of being explicit, and creating.
public class Service<TObject> : BaseService<TObject, IRepository<TObject>>

Related

Using Unity, how do you register type mappings for generics?

I'm trying to implement a repository solution for Entity Framework but I am having trouble registering the types that include generics using Unity.
Given:
// IRepository interface
public interface IRepository<TEntity>
{
// omitted for brevity
}
// Repository implementation
public class Repository<TEntity, TContext> : IRepository<TEntity>, IDisposable
where TEntity : class
where TContext : DbContext
{
// omitted for brevity
}
// service layer constructor
public MyServiceConstructor(IRepository<Account> repository)
{
_repository = repository;
}
I need to register the type mapping for IRepository to Repository. but I'm having trouble with the Unity syntax for this kind of mapping.
I have tried the following with no luck:
container.RegisterType<IRepository<>, typeof(Repository<,>)>();
container.RegisterType<typeof(IRepository<>), Repository<,>>();
EDIT
Based, on #Steven response I have the following implementation now:
// UnityRepository implementation
public class UnityRepository<TEntity> : Repository<TEntity, MyDbContextEntities>
where TEntity : class
{
public UnityRepository() : base(new MyDbContextEntities()) { }
}
// Unity bootstrapper
container.RegisterType(typeof(IRepository<>), typeof(UnityRepository<>));
You are trying to do the following:
container.RegisterType(typeof(IRepository<>), typeof(Repository<,>));
This would normally work, but won't do the trick in this case, since there is IRepository<TEntity> has one generic argument and Repository<TEntity, TContext> has two, and Unity (obviously) can't guess what type it should fill in for TContext.
What you need is this:
container.RegisterType(
typeof(IRepository<>),
typeof(Repository<, MyDbContextEntities>));
In other words, you'd want to supply the Repository<TEntity, TContext> as a partial open generic type (with one parameter filled in). Unfortunately, the C# compiler does not support this.
But even if the C# did support this, Unity doesn't support partial open generic types. In fact most IoC libraries eworks don't support this. And for that one library that does support it, you would still have to do the following (nasty thing) to create the partial open generic type:
Type myDbContextEntitiesRepositoryType =
typeof(Repository<,>).MakeGenericType(
typeof(Repository<,>).GetGenericParameters().First(),
typeof(MyDbContextEntities));
There's a easy trick work around to get this to work though: define a derived class with one generic type:
// Special implementation inside your Composition Root
public class UnityRepository<TEntity> : Repository<TEntity, MyDbContextEntities>
where TEntity : class
{
public UnityRepository([dependencies]) : base([dependencies]) { }
}
Now we can easily register this open generic type:
container.RegisterType(typeof(IRepository<>), typeof(UnityRepository<>));

How to inject IEnumerable using Microsoft Unity IOC container

I have a Service that need inject more than one provider, see below for example. How to use Unity to implement this feature?
public class MyService: IMyService
{
public MyService(IEnumerable<Provider> Providers);
}
I know this is an old question, but maybe this will help someone else that stumbles upon this.
As long as you register the implementations with a specific name, this is possible to easily inject. You will then get all registered implementations.
public class MyService: IMyService
{
public MyService(IProvider[] providers)
{
// Do something with the providers
}
}
Just make sure to inject them as an array. Unity will understand this. And when you register them you can register them as such:
container.RegisterType<IProvider, FooProvider>("Foo");
container.RegisterType<IProvider, BarProvider>("Bar");
One way is to inject the UnityContainer itself, and then resolve all the Providers you need:
public class MyService : IMyService
{
public class MyService(IUnityContainer iocContainer)
{
var providers = iocContainer.ResolveAll<IProvider>();
}
}
The only thing you will need to do is register the UnityContainer with itself somewhere on setup:
unityContainer.Register<IUnityContainer>(unityContainer, new ContainerControllerLifetimeManager());

How can I achieve this in Windsor Castle? (Migrating from StructureMap)

I need to modify an existing web app to use Castle.Windsor as IOC container. It was originally developed with StructureMap.
I am stuck with the following problem.
Lets say I have registered a couple of interfaces and their corresponding implementations:
IFoo -> Foo
IBar -> Bar
Calling container.Resolve<IFoo>() or container.Resolve<IBar>() works just fine. This means that the services are registered correctly.
I have a Web Api class with dependencies on other services, such as IFoo
public class BadRequestErrorHandler : HttpErrorHandler
{
// services
public BadRequestErrorHandler(IFoo foo) {...} // has dependency on IFoo
}
In StructureMap I can call:
var test = ObjectFactory.GetInstance<BadRequestErrorHandler>();
this will resolve the IFoo dependency.
Now this does not work with windsor.
How can this be achieved with windsor?
Thanks!
* EDIT *
I was just able to make it work by explicitely registering the BadRequestErrorHandler.
container.Register(Component.For<BadRequestErrorHandler>());
I am just hoping there is a better way to achieve this, that does not involve registering classes that have dependencies. I have a bunch of them...
* EDIT 2 **
To ease the pain, I added a special method to deal with these concrete types.
public T GetInstanceWithAutoRegister<T>()
{
if (container.Kernel.GetHandler(typeof(T)) == null)
{
container.Register(Component.For<T>());
}
return container.Resolve<T>();
}
public object GetInstanceWithAutoRegister(Type pluginType)
{
if (container.Kernel.GetHandler(pluginType) == null)
{
container.Register(Component.For(pluginType));
}
return container.Resolve(pluginType);
}
not ideal, but at least better than having to explicetly register each type. Hope someone has a better solution
You can achieve what you want by registering an ILazyComponentLoader which is a hook that gets called by Windsor as a "last resort" when a component cannot be resolved.
In your case, the implementation would probably look somewhat like this:
public class JustLetWindsorResolveAllConcreteTypes : ILazyComponentLoader
{
public IRegistration Load(string key, Type service)
{
return Component.For(service);
}
}
-and then it should be registered as such:
container.Register(Component.For<ILazyComponentLoader>()
.ImplementedBy<JustLetWindsorResolveAllConcreteTypes>());
You can read more about it in the docs.

Generic repository implementation with EF

For a simple repository
public interface ISimpleRepository<T>
{
IApplicationState AppState { get; set; }
void Add(T instance);
void Delete(T instance);
void Delete(Guid rowGuid);
IQueryable<T> GetAll();
T Load(Guid rowGuid);
void SaveChanges();
void Update(T instance);
}
my implementation of the Load() method for specific repository for class Product might look like this:
public Product Load(Guid rowid)
{
return (from c in _ctx.Products where c.id == rowid select c).FirstOrDefault();
}
Now this is assumed when my repository implementation class looks like this:
public class EntityFrameworkProductsProvider : IRepository<Product> ...
What if I had like dozens or hundreds of this small and simple entities that would all use the same behaviour when doing CRUDs (use the same implementation of methods)? I certainly don't want to go and create a class to implement IRepository for each one of them..
I want something like this:
public class EntityFrameworkDefaultProvider<T> : IRepository<T> ...
but I don't know how to implement the LINQ Select expression then because of course I can't write from e in _ctx.T where e... or do I?
I haven't run into this scenario yet because so far I only had very specific entities with custom repository implementation.
Because you tagged your question with entity-framework and entity-framework-4 I assume you are using ObjectContext API. ObjectContext offers method CreateObjectSet<T> which is equivalent of Set<T> on DbContext.
This question is actually duplicate of either:
Generic GetById with DbContext
Generic GetById with ObjectContext
Instead of writing _ctx.Products, you can write _ctx.Set<T>. That takes care of half of the problem (you need to add a generic constraint where T: class to your repository)
Then, if rowid is the object's key, you can use _ctx.Set<T>.Find(rowid) instead of a LINQ query to retrieve by Id.
Alternatively, you can create a base interface IHaveId (or a BaseEntity class, whatever you like) which has the Id property, and then add that as an generic constraint on T, so you can use it in your queries.
If you're using EF 4.1, see the sample generic repository here:
http://www.asp.net/entity-framework/tutorials/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
I know that this is possible in EF4.1 with the DbContext API, where you have a "Set" method on the context that gets you the entity set corresponding to the type T. this way, you could have your repository like this:
public class EntityFrameworkDefaultProvider<T> : IRepository<T> where T:class
{
public T Load(Guid rowId)
{
return _context.Set<T>().Find(rowId);
}
}
one more remark: I think you could use this syntax :
return _ctx.Products.FirstOrDefault(c=>c.id == rowid);
to get the entity you want instead of using the (from... in...). it's clearer (in my opinion) :)
Hope this helps

Importing dependencies using a class that inherits from Lazy<>

Can you import using a class that inherits from Lazy rather than Lazy itself? I am exporting using a derivitive of ExportAttribute that contains metadata.
[FeatureExport(/* Feature Metadata Parameters */)]
public class Feature : IFeature
{
// Feature Properties
}
public class FeatureReference : Lazy<IFeature, IFeatureMetadata>
{
}
public class Consumer
{
[ImportMany]
public IEnumerable<FeatureReference> FeatureReferences { get; set; }
}
Is this possible? Would it work? I could try it myself, but I'm in development so I don't actually have any code written.
No, it won't work I'm afraid. You would need to implement your own programming model extension (either a custom part/catalog or possibly via ReflectionModelServices) to make this work.
MEF would have to create the FeatureReference object in order to set it, and considering that FeatureReference might have any constructor imaginable, you can guess why this isn't supported.