Reputation: 48536
So far what I have is the following installer:
/// <summary>
/// Registers all repositories.
/// </summary>
public class RepositoryInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
AllTypes.FromAssemblyContaining<EntityFrameworkLinkRepository>()
.BasedOn<IRepository>()
.WithService.Select(ByConvention)
.Configure(WithDependencies)
.LifestylePerWebRequest()
);
}
private IEnumerable<Type> ByConvention(Type type, Type[] types)
{
if (type.BaseType == null || !type.Name.EndsWith(type.BaseType.Name))
{
return Enumerable.Empty<Type>();
}
return new[] { type.BaseType };
}
private void WithDependencies(ComponentRegistration component)
{
Type type = component.Implementation;
string key;
if (type.BaseType == null || !type.Name.EndsWith(type.BaseType.Name))
{
key = type.Name;
}
else
{
key = type.Name.Substring(0, type.Name.Length - type.BaseType.Name.Length);
}
component.DependsOn(new
{
connectionString = ConnectionString(key)
});
}
private string ConnectionString(string key)
{
string connectionString = Config.GetConnectionString(key);
return connectionString;
}
}
Which resolves the repositories.
Now, the repository is instanced like this:
public class EntityFrameworkLinkRepository : LinkRepository
{
private readonly ObjectDataContext context; // TODO shouldn't this be receiving a lifetimed ODC, instead of just the connString?
public EntityFrameworkLinkRepository(string connectionString)
{
if (connectionString == null)
{
throw new ArgumentNullException("connectionString");
}
this.context = new ObjectDataContext(connectionString);
}
// etc...
My question here is how I should be resolving the object data context, rather than just creating a new one (and not even disposing of it), what's the correct way to resolve an EF data context through Castle using DI?
I guess I would like the ODC to be shared across all repositories that pertain to the same web request (that would be the way that makes the most sense to me, right?)
But since my implementation of ObjectContext
is specific to EntityFramework
, I'm kind of lost as to how I'm supposed to resolve it, should I explicitly register it with something like this?
container.Register(
Component
.For<ObjectDataContext>()
.DependsOn(new
{
connectionString = ConnectionString("EntityFramework")
})
.ImplementedBy<ObjectDataContext>()
);
Upvotes: 0
Views: 1509
Reputation: 21996
You should be taking a constructor parameter for the ObjectDataContext. If you're using MVC you should also implement a WindsorControllerFactory, so all you controller get created by Windsor and any constructor dependencies get created for you. You shouldn't need to create and instances of anything "servicey"
How you register your ObjectDataContext really depends on what interface/class you have written things to, that depend on it. So, if you've written your code to ObjectDataContext itself, then the example you gave is fine. But if you wrote to an interface then something like this would be needed ...
container.Register(
Component
.For<IObjectDataContext>()
.ImplementedBy<ObjectDataContext>()
.DependsOn(new { connectionString = ConnectionString("EntityFramework") })
.LifeStyle.PerWebRequest
);
Upvotes: 2
Reputation: 233317
Something like this ought to work:
container.Register(
.Component.For<ObjectDataContext>()
.DependsOn(
Dependency.OnValue(
"connectionString", ConnectionString("EntityFramework")))
.LifeStyle.PerWebRequest);
Upvotes: 4