Wayne Allen
Wayne Allen

Reputation: 1735

Unity.Resolve for a class with a dependency injection

I am using Unity to control Dependency Injection in my Xamarin Forms application. I have a view model class that takes a parent id and a unity injected service as constructor parameters.

public class BrowseViewModel {
    public BrowseViewModel(int parentId, IInjectedService injectedService) {
    }
}

I have registered the class in the unity container.

unityContainer.registerType<BrowseViewModel>();

I have also registered the service in the unity container.

unityContainer.registerType<IInjectedService, InjectedService>();

My question is, how do I specify the value for parentId when Unity creates an instance of my class? I don't think I should have to specify the injectedService parameter because I have already registered this class with unity and it is a singleton class.

Upvotes: 0

Views: 1361

Answers (3)

George Alexandria
George Alexandria

Reputation: 2936

Additionally, you can set the parentId when you try to resolve BrowserViewModel.

At first, just register type:

        container.RegisterType<BrowseViewModel>();
        // Mark that InjectedService is the singleton using ContainerControlledLifetimeManager
        container.RegisterType<IInjectedService, InjectedService>(new ContainerControlledLifetimeManager());

And then resolve type. For this you need to override all primitive types in constructor when try to resolve a type, so you can use ParameterOverrides as pointed out in the answer by @Crekate or can directly put params ParameterOverride as in the code below:

        var vm = container.Resolve<BrowseViewModel>(new ParameterOverride("parentId", 546));

Upvotes: 0

Crekate
Crekate

Reputation: 145

You need to register BrowseViewModel like that:

container.RegisterType<Func<int, BrowseViewModel>>(
                new InjectionFactory(c =>
                    new Func<int, BrowseViewModel>(id=> c.Resolve<BrowseViewModel>(new ParameterOverrides { { "parentId", id},))));

Then in contrutor where you use BrowseViewModel, you need to use Func<int, BrowseViewModel> browseViewMdoelFactory and use it like that:

class SomeViewClass
{
    SomeViewClass(Func<int, BrowseViewModel> browseViewMdoelFactory)
    {    
    browsceViewModelFactory(parentId);
    }
}

Upvotes: 0

Zenuka
Zenuka

Reputation: 3250

You have a couple of options. You can register your BrowserViewModel like this:

unityContainer.RegisterType<BrowseViewModel>(new InjectionFactory(c => new BrowseViewModel(1234, c.Resolve<IInjectedService>())));

But this way you have a fixed value for parentId (1234 in this example).

You could also use a factory design pattern like so:

public class BrowseViewModelFactory
{
    private IInjectedService _injectedService;
    public BrowseViewModelFactory(IInjectedService injectedService)
    {
        _injectedService = injectedService;
    }
    public BrowseViewModel CreateBrowseViewModel(int parentId)
    {
        return new BrowseViewModel(parentId, _injectedService);
    }
}

Then you inject the BrowseViewModelFactory in class you need the BrowseViewModel and call the create method with the correct parentId. Like:

public class SomeOtherClass
{
    private BrowseViewModelFactory _browseViewModelFactory;
    public SomeOtherClass(BrowseViewModelFactory browseViewModelFactory)
    {
        _browseViewModelFactory = browseViewModelFactory;
    }

    public void DoStuff()
    {
        var browseViewModel = _browseViewModelFactory.CreateBrowseViewModel(4321);
    }
}

Upvotes: 2

Related Questions