Injecting Runtime Objects Using Lamar

993 Views Asked by At

I'm trying to build a package for Lamar for a framework which I maintain. To show what I mean by reference to StructureMap, the relevant method which was able to mix a runtime object with Service abstractions is (where the container is passed in to the constructor of this factory class):

public IPresenter Create(Type presenterType, Type viewType, IView viewInstance)
{
    container.Configure(x => x.For(presenterType)
        .Use(presenterType)
        .Named(presenterType.Name)
        );

    var args = new ExplicitArguments();
    args.Set("view");
    args.SetArg("view", viewInstance);

    return (IPresenter)container.GetInstance(presenterType, args);
}

I realise that Lamar does not implement ExplicitArguments (fair enough).

I played around with the Injectable feature, but was no able to get that to work:

public IPresenter Create(Type presenterType, Type viewType, IView viewInstance)
{
    var c = _container.GetNestedContainer();
    c.Inject(viewInstance);

    // return c.GetInstance(presenterType, presenterType.Name.ToString()) as IPresenter; // BOOM!!!

    return _container.GetInstance(presenterType) as IPresenter; // BOOM!!!
}

Is there an alternative way in Lamar?

This is my registration code:

IContainer container = new Container(c =>
{
    c.AddTransient<ISomeService, SomeService>();
    c.Injectable<IMainView>();
    c.AddTransient<MainPresenter>();
});    

I have created a sample project which recreates the issue which can be downloaded here. It uses .NET 5

In that project, if you put a break-point in the class MainPresenter, you will see that the IView parameter is null and the OrdersService does resolve.

I need that concrete object, which is the main form, to be passed in as well (as the IView).

Cheers

1

There are 1 best solutions below

3
oleksa On

there is a problem with LamarPresenterFactory.Create method viewInstance parameter

public IPresenter Create(Type presenterType, Type viewType, IView viewInstance)
{
}

I've noticed that it should be of IMainView type like below

public IPresenter Create(Type presenterType, Type viewType, IMainView viewInstance)
{
    var nestedContainer = _container.GetNestedContainer();
    nestedContainer.Inject(viewInstance);

    return nestedContainer.GetInstance(presenterType) as IPresenter;
}

nestedContainer.Inject(viewInstance) parameter data type requires viewInstance to be the same type that was used with c.Injectable<IMainView>();

I'm getting OrdersService.GetOrders exception since there is no orders.zip file available