How to use constructor injection?

61 views
Skip to first unread message

Whoever

unread,
Mar 12, 2012, 9:36:37 AM3/12/12
to agatha
I have something like this:

- UserListRequest, UserListResponse, UserListHandler.
- UserRepository : IUserRepository

I use StructureMap in my project, so I'm trying to apply it here too.
So far I have done

x.Scan(z => { z.Assembly("MyAssembly");
z.WithDefaultConventions();});

and in the handler

IUserRepository repository =
ObjectFactory.GetInstance<IUserRepository>();

and it works fine. But I read that it's better to use constructor
injection than hard-coded structuremap.

I have no idea where to put it. I tried to create constructor in the
handler class, or create a Handle with additional parameters, but
nothing work so far.

Anyone? Thanks.


Whoever

unread,
Mar 12, 2012, 2:24:50 PM3/12/12
to agatha
I also read about using setter injection,

public IUserRepository repository {get;set;}

public override Handle(...)
repository.GetUserList()

in the handler, but couldn't figure out how to configure
StructureMap. It always says null reference.

shapper

unread,
Mar 12, 2012, 5:26:18 PM3/12/12
to agath...@googlegroups.com
Hello,

This is how I use StructureMap with Agatha:

  public class CreateUserHandler : RequestHandler<CreateUserRequest, CreateUserResponse> {

    private IRepositoryFactory _repositories;

    public CreateUserHandler(IRepositoryFactory repositories) {
      _repositories = repositories;
    } // CreateUserHandler

    public override Response Handle(CreateUserRequest request) {
    }

And my Structure Map configuration is something as:

      For<IRepositoryFactory>().HttpContextScoped().Use<RepositoryFactory>();

      Scan(x => {
        x.AssemblyContainingType(typeof(IRepository<>));
        x.AddAllTypesOf(typeof(IRepository<>));
        x.ConnectImplementationsToTypesClosing(typeof(Repository<>));
        x.WithDefaultConventions();
      });

Cheers,
Miguel

Whoever

unread,
Mar 12, 2012, 10:52:17 PM3/12/12
to agatha
Thanks.

I couldn't make this part compile

Scan(x => {
x.AssemblyContainingType(typeof(IRepository<>));
x.AddAllTypesOf(typeof(IRepository<>));
x.ConnectImplementationsToTypesClosing(typeof(Repository<>));
x.WithDefaultConventions();
});

If I take out all the <>s, it runs, but I got the same error when
calling the service. I also play around several variation of this,
but still can't make it work.

Would you mind give me some more details about the structuremap
config? Thanks

Davy Brion

unread,
Mar 13, 2012, 5:42:22 AM3/13/12
to agath...@googlegroups.com
You have to make sure that Agatha is using the same IOC container instance as the one you're registering your dependencies with.

so basically, use the ServiceLayerConfiguration constructor with an IContainer parameter (https://github.com/davybrion/Agatha/blob/master/Agatha.ServiceLayer/ServiceLayerConfiguration.cs#L33), and pass in the wrapped container.  If you're using structuremap, an Agatha.StructureMap.Container instance, created through the constructor that allows you to pass in your structuremap container issue (https://github.com/davybrion/Agatha/blob/master/Agatha.StructureMap/Container.cs#L21)

both constructor injection and setter injection should then work correctly

shapper

unread,
Mar 13, 2012, 6:12:12 AM3/13/12
to agath...@googlegroups.com
I have my Agatha configuration as follows:

      new ServiceLayerAndClientConfiguration(typeof(CreateUserHandler).Assembly, typeof(CreateUserRequest).Assembly, new Agatha.StructureMap.Container(ObjectFactory.Container)).Initialize();

Cheers,
Miguel

Whoever

unread,
Mar 21, 2012, 3:59:02 PM3/21/12
to agatha
Still having trouble figuring this one out. In my service host
project, global.aspx, I have agatha service registration

new ServiceLayerConfiguration(Assembly.GetExecutingAssembly(),
typeof(PingRequest).Assembly,
typeof(Agatha.StructureMap.Container))
.RegisterRequestHandlerInterceptor<AuditInterceptor>()
.RegisterRequestHandlerInterceptor<ValidationInterceptor>()
.RegisterRequestHandlerInterceptor<AuthorizationInterceptor>()
.Use<RequestHandlerBasedConventions>().Initialize();

Here's my dependency registration (I know I must have missed something
here, it should be part of service layer registration?)

ObjectFactory.Configure(x => {

x.For<IRepository>().Use<GenericRepository>().Ctor<string>("connectionStringName").Is("DefaultDb");
x.Scan(y => { y.Assembly("Portal.Service");
y.WithDefaultConventions(); }); });

Here's a handler

public class TestListHandler : PortalHandler<TestListRequest,
TestListResponse> {
private IRepository _repository;
public TestListHandler(IRepository repository) {
_repository = repository; }

When debugging, I always got something like no default plugin family
for IRepository exception. I can use
ObjectFactory.GetInstance<IRepository>() or
ObjectFactory.GetInstance<ITestRepository>(), etc.

How do I "make sure that Agatha is using the same IOC container
instance as the one you're registering your dependencies with"?
Thanks.


Bart Deleye

unread,
Mar 21, 2012, 5:03:53 PM3/21/12
to agath...@googlegroups.com
You can provide your own container instance like this:
new ServiceLayerConfiguration(Assembly.GetExecutingAssembly(),
  typeof(PingRequest).Assembly,
new Agatha.StructureMap.Container(ObjectFactory.Instance) )

Whoever

unread,
Mar 22, 2012, 11:14:15 AM3/22/12
to agatha
Now I see.  shapper actually already gave me the answer in his reply,
I just didn't realize what it is.

Thanks.  Your guys are great!

On Mar 21, 5:03 pm, Bart Deleye <bart.del...@gmail.com> wrote:
> You can provide your own container instance like this:
> new ServiceLayerConfiguration(Assembly.GetExecutingAssembly(),
>   typeof(PingRequest).Assembly,
> new Agatha.StructureMap.Container(ObjectFactory.Instance) )
>
>
>
>
>
>
>
> On Wed, Mar 21, 2012 at 8:59 PM, Whoever <zhang...@gmail.com> wrote:
> > Still having trouble figuring this one out. In my service host
> > project, global.aspx, I have agatha service registration
>
> > new ServiceLayerConfiguration(Assembly.GetExecutingAssembly(),
> >   typeof(PingRequest).Assembly,
> > typeof(Agatha.StructureMap.Container))
> >   .RegisterRequestHandlerInterceptor<AuditInterceptor>()
> >   .RegisterRequestHandlerInterceptor<ValidationInterceptor>()
> >   .RegisterRequestHandlerInterceptor<AuthorizationInterceptor>()
> >   .Use<RequestHandlerBasedConventions>().Initialize();
>
> > Here's my dependency registration (I know I must have missed something
> > here, it should be part of service layer registration?)
>
> > ObjectFactory.Configure(x =>   {
>
> > x.For<IRepository>().Use<GenericRepository>().Ctor<string>("connectionStrin gName").Is("DefaultDb");
Reply all
Reply to author
Forward
0 new messages