4

This is my current implementation of StructureMap in Global.asax:

var container = (IContainer)IOCContainer.Initialize();
DependencyResolver.SetResolver(new StructureMapDependencyResolver(container));

Below is the code that is refered to above:

public static class IOCContainer
    {
        public static IContainer Initialize()
        {
            ObjectFactory.Initialize(x =>
            {
                x.Scan(scan =>
                {
                    scan.TheCallingAssembly();
                    scan.WithDefaultConventions();
                    scan.AddAllTypesOf<IController>();
                });

                x.For<IConfigRepository>().Use<ConfigRepository>();
            });
            return ObjectFactory.Container;
        }

    }

public class StructureMapDependencyResolver : IDependencyResolver
    {
        public StructureMapDependencyResolver(IContainer container)
        {
            _container = container;
        }

        public object GetService(Type serviceType)
        {
            if (serviceType.IsAbstract || serviceType.IsInterface)
            {
                return _container.TryGetInstance(serviceType);
            }
            else
            {
                return _container.GetInstance(serviceType);
            }
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            return _container.GetAllInstances<object>()
                .Where(s => s.GetType() == serviceType);
        }

        private readonly IContainer _container;
    }

I have read that using the shared connection may improve performance a little bit so I was wondering how to use this in my MVC app. I guess I would have to pass a newly created PetaPoco.Database object to the constructors of my repositories??

Thanks

Jon
  • 38,814
  • 81
  • 233
  • 382

3 Answers3

3

I can only speak for Autofac as that's what I use in my project. This might not apply to what you're trying to do but I might as well share it. To get a petapoco database object per http request I have this config in global.asax.cs

builder.RegisterType<MyProject.ObjectRelationalMapper.PetaPoco.Database>()
                .As<MyProject.ObjectRelationalMapper.PetaPoco.Database>()
                .WithParameters( new List<NamedParameter>() {new NamedParameter( "connectionStringName", "MyProjectConnectionString")})
                .InstancePerHttpRequest();

MyProject.ObjectRelationalMapper.PetaPoco is just my renameapaced petapoco.cs.

In Autofac you can tell it which version of the constructor to call by telling it which parameters you are passing in via WithParameters(). When constructing your object it finds the constructor with matching parameters.

Every time a constructor has its dependencies injected it uses the same petapoco database object throughout the http request, because that's what I told Autofac to do (InstancePerHttpRequest)

My controller constructor takes an INextMatchService as a dependency which in turn takes an INextMatchRepository as a dependency :

public NextMatchRepository( Database database, ISessionWrapper sessionWrapper)
{
    this._database = database;
    this._sessionWrapper = sessionWrapper;
}

The "Database" type is MyProject.ObjectRelationalMapper.PetaPoco.Database, which is constructed in the above code snippet. Now my repository can work with a shared database connection. As you work with the Petapoco functions it checks if there is already a connection to use, if there is it increments the counter and uses the object :

// Open a connection (can be nested)
public void OpenSharedConnection()
{
    if (_sharedConnectionDepth == 0)
    {
        _sharedConnection = _factory.CreateConnection();
        _sharedConnection.ConnectionString = _connectionString;
        _sharedConnection.Open();

        if (KeepConnectionAlive)
            _sharedConnectionDepth++;// Make sure you call Dispose
    }
    _sharedConnectionDepth++;
}
Typo Johnson
  • 5,974
  • 6
  • 29
  • 40
  • Thanks. I've just thought of another problem. How do you do unit tests to see if the application is using the shared connection? – Jon Sep 16 '11 at 10:41
  • Also, I may be missing something but if you have a repo that does a Fetch of Person for example it will close it again because it does sql's one at a time. If you have 5 requests on your web app will it be at that point it will use the already created object? – Jon Sep 16 '11 at 11:07
2

I went with this if anyone wants to know:

x.For<PetaPoco.Database>().Singleton().Use(() => new PetaPoco.Database("DBConnection"));
Jon
  • 38,814
  • 81
  • 233
  • 382
0

When you run the T4 that you get with PetaPoco you will get the following available..

{yourmodel}.ConnectionStringDB.GetInstance();

I this looks for an instace, if there is one then it uses it if not it creates another.

I could be wrong on that though.. I cant fully remember.

David McLean
  • 1,462
  • 1
  • 12
  • 27
  • I'm not using T4 unfortunately – Jon Sep 15 '11 at 18:45
  • Yup as the database I have has nasty uppercase and underscores all over the place for column names so I am creating the POCO and decorating the properties with the column name to keep the code clean – Jon Sep 15 '11 at 19:41