Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I am using Castle Windsor as my IoC container and I registered it as a DependencyResolver to let the MVC framework know about it.

With the Entity Framework I have this DbContext:

public class MyDbContext : DbContext
{
    public DbSet<User> Users { get; set; }
}

In Castle Windsor it is registered as per web request:

container.Register(
    Component.For<DbContext, MyDbContext>()
             .ImplementedBy<MyDbContext>()
             .LifestylePerWebRequest()
);

Because I don't have control over creating the MyMembershipProvider object, this object is created once per web application so it is not possible to inject DbContext directly, because it will be disposed when the web request ends. So I wrote this as a solution:

public interface IDoInContext<TContext>
{
    void DoInContext(Action<TContext> action);
}

public class DoInMyDbContext : IDoInContext<MyDbContext>
{
    IKernel _kernel;

    public DoInMyDbContext(IKernel kernel)
    {
        _kernel = kernel;
    }

    public void DoInContext(Action<MyDbContext> action)
    {
        var context = _kernel.Resolve<MyDbContext>();
        action(context);
        _kernel.ReleaseComponent(context);
    }
}

And I registered like this:

container.Register(
    Component.For<IDoInContext<MyDbContext>>()
             .ImplementedBy<DoInMyDbContext>()
             .LifestyleSingleton()
);

So now I can create a MyMembershipProvider which will be able to interact with the current and correct DbContext every time it needs.

public class MyMembershipProvider : MembershipProvider
{
    IDoInContext<MyContext> db;

    public MyMembershipProvider()
        : this(DependencyResolver.Current.GetService<IDoInContext<MyContext>>())
    { }

    public MyMembershipProvider(IDoInContext<MyContext> db)
    {
        this.db = db;
    }

    public override bool ValidateUser(string username, string password)
    {
        bool result = false;
        db.DoInContext(x => {
            var encodedPassword = encodePassword(password);
            result = x.Users.Any(y => y.Login == username && 
                                      y.Password == encodedPassword);
        });
        return result;
    }

    ...
}

It seems to be stable and I can't see any memory leaks or any other problems. What do you think? Is the DoInContext(Action<TContext> action) thing any sort of pattern, anti-pattern or bad practice?

share|improve this question
    
Why exactly do you say the MyDbContext cannot be injected directly? I'm trying to see if I understand what you mean, so I could help you out. –  TopinFrassi Oct 7 at 12:36

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.