Tuesday, September 25, 2012

Func Injection in Unity

Let your container be your factory. :)

If you are using LinqToSql and dependency injection, then you have probably created a factory with which you create DataContexts. But what if you could just let your IOC Container do that work for you? You can!

If you are using Unity then you can inject a Func<T> of any registered type. Unity will automatically bind the injected Func to the container's resolve method, thus preserving the resource Lifetime Manager.

Example Code

public class FuncInjectionTests
{
    [Fact]
    public void TransientLifetimeFuncIsThreadsafe()
    {
        var container = new UnityContainer();
 
        container
            .RegisterType<IUserService, UserService>(
                new ContainerControlledLifetimeManager())
            .RegisterType<IDataContext, DataContext>(
                new TransientLifetimeManager());
 
        var parallelOptions = new ParallelOptions {MaxDegreeOfParallelism = 100};
 
        Parallel.For(0, 1000, parallelOptions, i =>
        {
            var userService = container.Resolve<IUserService>();
 
            Parallel.For(0, 1000, parallelOptions, j =>
            {
                userService.Update();
            });
        });
 
        Assert.Equal(1, UserService.Count);
        Assert.Equal(1000000, DataContext.Count);
    }
}
 
public interface IUserService
{
    void Update();
}
 
public interface IDataContext : IDisposable
{
    void UpdateUser();
}
 
public class UserService : IUserService
{
    public static int Count;
 
    private readonly Func<IDataContext> _dataContextFactory;
 
    public UserService(Func<IDataContext> dataContextFactory)
    {
        _dataContextFactory = dataContextFactory;
        Interlocked.Increment(ref Count);
    }
 
    public void Update()
    {
        using (var dataContext = _dataContextFactory())
            dataContext.UpdateUser();
    }
}
 
public class DataContext : IDataContext
{
    public static int Count;
 
    public DataContext()
    {
        Interlocked.Increment(ref Count);
    }
 
    public void UpdateUser()
    {
        Trace.WriteLine(Thread.CurrentThread.ManagedThreadId + " - " + Count);
    }
 
    public void Dispose()
    {
    }
}
Shout it

Enjoy,
Tom

7 comments:

  1. Didn't knew that IOC Container can manage this so well. But still I think there will be some limitation to it. I am new to ASP.NET and it would be great help if you let me know this clearly.

    ReplyDelete
  2. This pattern has worked flawlessly for me. What limitations are you concerned about?

    ReplyDelete
  3. Great write-up, I am a big believer in commenting on blogs to inform the blog writers know that they’ve added something worthwhile to the world wide web!.. 2k injection molding

    ReplyDelete
  4. Hi, constantly i used to check blog posts here in the early hours in the daylight, as i love
    to gain knowledge of more and more wecare riteaid com

    ReplyDelete
  5. well written post. It`s so useful…thank you
    pandoralistens net

    ReplyDelete
  6. Nice article,Having concern on wild life..Its’s good to think on wild life because we human ready acquired all over earth. It means we taking land if wild animal for human usage.. That DNA talk is perfect..Thank you introduce some new concepts in mind..keep it up..

    greatpeople me kroger employee login-portal

    ReplyDelete
  7. play on our online poker game and get the blessings
    judi togel
    slot gacor hari ini

    ReplyDelete

Real Time Web Analytics