How to use autofac methodinjection?

177 views
Skip to first unread message

Alexander Goida

unread,
Jan 28, 2014, 11:36:17 PM1/28/14
to aut...@googlegroups.com
Hi,


But the meaning of this is slipping away from me. Could somebody show me reliable example of using this approach in practice?

Thanks,

Kendall Bennett

unread,
Jan 29, 2014, 2:49:37 PM1/29/14
to aut...@googlegroups.com
On thing that I have been thinking would be really nice, and would potentially be another way to solve my circular dependency problem, would be to have a way of automatically wiring up an Initialize() function that would behave just like a constructor, but would be called AFTER all the objects have been created and activated. Then we can use constructor style injection rather than property injection, but it would happen after the graph has been created. Assuming the activation sequence is done in the correct order, such that the deepest objects are activated first, I think this would work?

The catch right now with method activation is you have to write a lot of code to wire it up. It would be much nicer if we could just do something like:

builder.Register<OrderSystem>().As<IOrderSystem>().OnActivateInitialize()

or something like that. Then not have to do anything else. It would then look for a method like this:

void Initialize(IBlah blah, IFoo foo, IBar bar)

and would call it with all the necessary objects already correctly created before Initialize is called. The catch is the activator would have to track all of the dependencies by looking the up when it calls the constructor, so it can make sure it constructs them all, and then as the last step go ahead and run the activation when the root of the graph has been constructed?

Do you guys think this is feasible, or am I not thinking straight?

Regards,

Kendall Bennett, CEO 
http://www.AMainHobbies.com
1-800-705-2215 (Toll-Free)
1-530-894-0797 (Local)

Facebook | Twitter | Youtube

On Jan 29, 2014, at 8:07 AM, Travis Illig <travis...@gmail.com> wrote:

Say you have some code that only allows you to set a property through a method rather than through a formal property (for whatever reason).

public interface IOrderSystem
{
  void MakeOrder(Order o);
}

public class OrderSystem : IOrderSystem
{
  public IRepository OrderRepository { get; private set; }

  public void SetRepository(IRepository repo)
  {
    this.OrderRepository = repo;
  }

  public void MakeOrder(Order o)
  {
    this.OrderRepository.AddOrder(o);
  }
}

Given a situation like that, you can't use constructor or property injection, but you can still take advantage of the method to automatically wire up the repository to the order system.

var builder = new ContainerBuilder();
builder.RegisterType<Repository>().As<IRepository>();
builder.Register<OrderSystem>().As<IOrderSystem>()
  .OnActivating(e => {
    var repo = e.Context.Resolve<IRepository>();
    e.Instance.SetRepository(repo);
  });
var container = builder.Build();

// The repo will already be set on the order system with no additional work:
var orderSystem = container.Resolve<IOrderSystem>();

--
You received this message because you are subscribed to the Google Groups "Autofac" group.
To unsubscribe from this group and stop receiving emails from it, send an email to autofac+u...@googlegroups.com.
To post to this group, send email to aut...@googlegroups.com.
Visit this group at http://groups.google.com/group/autofac.
For more options, visit https://groups.google.com/groups/opt_out.

Alexandr Nikitin

unread,
Jan 30, 2014, 11:44:06 AM1/30/14
to aut...@googlegroups.com

Temporal Coupling is a bad practice IMHO, Mark Seemann explains why. I wouldn't support this feature :)

Kendall Bennett

unread,
Jan 31, 2014, 3:19:51 PM1/31/14
to aut...@googlegroups.com
I am confused. Why do you think this is temporary coupling? What I am trying to do is be able to use Constructor like injection via an Initiliaze() method that handles circular references, but makes sure the classes are fully resolved before Initialize() is called. We use it with property injection now, and have internal Init() functions we have to call all over the place. I would like to be able to do that just once when the class is finalized.


Regards,

Kendall Bennett, CEO 
http://www.AMainHobbies.com
1-800-705-2215 (Toll-Free)
1-530-894-0797 (Local)

Facebook | Twitter | Youtube

Travis Illig

unread,
Jan 29, 2014, 11:07:13 AM1/29/14
to aut...@googlegroups.com
Say you have some code that only allows you to set a property through a method rather than through a formal property (for whatever reason).

public interface IOrderSystem
{
  void MakeOrder(Order o);
}

public class OrderSystem : IOrderSystem
{
  public IRepository OrderRepository { get; private set; }

  public void SetRepository(IRepository repo)
  {
    this.OrderRepository = repo;
  }

  public void MakeOrder(Order o)
  {
    this.OrderRepository.AddOrder(o);
  }
}

Given a situation like that, you can't use constructor or property injection, but you can still take advantage of the method to automatically wire up the repository to the order system.

var builder = new ContainerBuilder();
builder.RegisterType<Repository>().As<IRepository>();
builder.Register<OrderSystem>().As<IOrderSystem>()
  .OnActivating(e => {
    var repo = e.Context.Resolve<IRepository>();
    e.Instance.SetRepository(repo);
  });
var container = builder.Build();

// The repo will already be set on the order system with no additional work:
var orderSystem = container.Resolve<IOrderSystem>();

On Tuesday, January 28, 2014 8:36:17 PM UTC-8, Alexander Goida wrote:
Reply all
Reply to author
Forward
0 new messages