Question

My service uses a utility class and that utility class has several public properties. Is there something special I need call to ensure these public properties are setup?

The service uses a ASP.NET host. Inside of Global.ASAX I have declared a new AppHostBase:

public class MyServiceHost : AppHostBase
{
    public MyServiceHost() : base("My Service Host", typeof(ServiceLibrary).Assembly) {}

    public override void Configure(Funq.Container container)
    {
        container.Register<IDbConnectionFactory>(dbConFactory);

        container.RegisterAutoWired<UtilityLibrary>();
        container.RegisterAutoWired<RepositoryLibrary>();
    }
}

Within both my repository library and utility library is a main class. This may class receives the Container and registers more specific utilities and repositories:

public class UtilityLibrary
{
    public UtilityLibrary(Funq.Container container)
    {
        container.RegisterAutoWired<WidgetAActions>();
        container.RegisterAutoWired<WidgetBActions>();
    }
}

In the example below, WidgetARepository was set in the constructor of the RepositoryLibrary class. The RepositoryLibrary class, which contains the WidgetARepository, was supplied to the Container in the Configure method of the AppHost (first snippet above). Even still, the WidgetARepository (below) is never set:

public class WidgetAActions
{
    public WidgetARepository WidgetARepository { get; set; }

    public WidgetA Get(string id)
    {
        var item = this.WidgetARepository.Get(id);
        if (item == null) { return null; }

        // Do something else

        return item;
    }
}

Must I manually call Resolve()? This seems like it would defeat the purpose of injection by doing this.

Was it helpful?

Solution

If you are using wanting to use the Funq Container Autowire IoC outside of the ServiceStack service then you need to call Container.AutoWire yourself to have the container inject the relevant dependencies. This call is made behind the scenes in the ServiceStack request pipeline.

For ServiceStack v4:

HostContext.Container.AutoWire(objectToPopulate);

For ServiceStack v3:

AppHostBase.Instance.Container.AutoWire(objectToPopulate);

I would typically add this call to the construtor method of the object I want populated with the injections. So in your case:

public class WidgetAActions
{
    public WidgetARepository WidgetARepository { get; set; }

    public WidgetAActions()
    {
        // (Substitute with v3 usage if required.)
        HostContext.Container.AutoWire(this);
    }

    ...
}

Hope this helps.


Edit: Have you considered having the container inject the corresponding repository to WidgetAActions's constructor?

container.RegisterAutoWired<WidgetAActions>(c => new WidgetAActions(c.Resolve<WidgetARepository>()));

public class WidgetAActions
{
    public WidgetARepository WidgetARepository { get; private set; }

    public WidgetAActions(WidgetARepository repository)
    {
        WidgetARepository = repository;
    }

    ...
}

Edit: Or you could resolve and set the public property of your object to the repository and then you don't have to have a constructor:

container.RegisterAutoWired<WidgetAActions>(c => 
    new WidgetAActions { WidgetARepository = c.Resolve<WidgetARepository>() }
);

public class WidgetAActions
{
    public WidgetARepository WidgetARepository { get; set; }

    ...
}

Or you could call autowire at time of resolving WidgetAActions:

container.RegisterAutoWired<WidgetAActions>(c => {
    var actions = new WidgetAActions();
    container.AutoWire(actions); // All dependencies injected
    return actions;
});

public class WidgetAActions
{
    public WidgetARepository WidgetARepository { get; set; }

    ...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top