Resolve only activated instances

10 views
Skip to first unread message

jonathan...@hotmail.com

unread,
Jun 27, 2008, 11:47:05 AM6/27/08
to Autofac
Nick,

Is there a way to resolve only activated instances? In my repository
code I'm trying to inject a unit of work into them only if one has
already been created, otherwise either null or a null object will be
injected.

I was looking through the source and it appears that OnPreparing could
be a possibility because it's called isn't an instance already
available (_scope.InstanceAvailable). I'd have to use the Null Object
Pattern to inject a non-null object during OnPreparing - but it
appears that instance

One possibility would be to use the Null Object Pattern, but it
appears that the null object provided during OnPreparing would be used
in any future calls to Resolve<>.

The idea is to have the repository use a unit of work if available
otherwise to perform the persistence operation right then and there.

Tyler Tipton

unread,
Jun 27, 2008, 12:38:55 PM6/27/08
to aut...@googlegroups.com
Why not just have your code insert an already created instance into the container?

I just set up simple factories for creating and adding instances to the container rather than using a registration in this situation. Or if you need the UoW instances to be built by the container also then you could consider using tagged instances.

-Tyler

Nicholas Blumhardt

unread,
Jun 27, 2008, 6:41:33 PM6/27/08
to aut...@googlegroups.com
public class UnitOfWorkTracker
{
  public UnitOfWork CurrentUnitOfWork { get; set; }
}

builder.Register<UnitOfWorkTracker>().ContainerScoped();

builder.Register(c => {
  var result = new UnitOfWork();
  c.Resolve<UnitOfWorkTracker>().CurrentUnitOfWork = result;
  return result;
}).ContainerScoped();

builder.Register(c => new SomeRepository() { UoW = c.Resolve<UnitOfWorkTracker>().CurrentUnitOfWork) })
  .ContainerScoped();

:) ? Just the first thing that came to mind. May not be the nicest if you want to autowire your repositories. There might be other variations on the UnitOfWorkTracker theme.

A better approach might be:

builder.Register(c => someCondition ? new UnitOfWork() : new NullUnitOfWork())
  .As<IUnitOfWork>()
  .ContainerScoped();

... That one depends on what that condition is.

Tyler was onto something too:

builder.Register(c => c.Resolve<UnitOfWorkTracker>().CurrentUnitOfWork).ContainerScoped();

That way you could put an instance in the UnitOfWorkTracker.CurrentUnitOfWork property when a 'real' UoW is going on (the value could be still be resolved from the container, perhaps by name.)

I think the second approach is the cleanest because within a nested container there will either be a UnitOfWork proper, or a NullUnitOfWork, never both. If this is not possible in your design, look closely at how the inner container corresponds with a unit of work - it probably should be 1-1.

I'd guess there are many other approaches - some of them a bit crazier than others.

Hope this helps

NB
Reply all
Reply to author
Forward
0 new messages