Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unity (dependency injection): How to pass in a parameter to the constructor in RegisterType

Can anyone help?

I have a wpf app (shouldn't matter) and in the Onstart i have my bootstrap stuff.. Its like this..

        // Create unity container my service and repository
        container = new UnityContainer()
            .RegisterType<ISecurityRepository, SecurityRepository>()
            .RegisterType<ISecurityService, SecurityService>();

Basically ISecurityService expects me to pass in a ISecurityRepository, hence the above fails.

But i am little confused, do i have to create a new IsecurityRespository and then pass it in, this defeats the object doesn't it?

Is there anyway i say "pass into SecurityService the ISecurityRepository from the container", but it hasn't been built yet?

Any ideas?

like image 864
mark smith Avatar asked Sep 27 '09 14:09

mark smith


2 Answers

You don't have to create instances first. It all just works. That's the magic of IoC Containers.

Example:

public interface ISecurityService { }
public interface ISecurityRepository { }

public class SecurityService : ISecurityService
{
    public SecurityService(ISecurityRepository repository)
    {
        Console.WriteLine("SecurityService created");
        Console.WriteLine("Repository is " + repository);
    }

    public override string ToString()
    {
        return "A SecurityService";
    }
}

public class SecurityRepository : ISecurityRepository
{
    public SecurityRepository()
    {
        Console.WriteLine("SecurityRepository created");
    }

    public override string ToString()
    {
        return "A SecurityRepository";
    }
}

public class MyClassThatNeedsSecurity
{
    public MyClassThatNeedsSecurity(ISecurityService security)
    {
        Console.WriteLine("My class has security: " + security);
    }
}

class Program
{
    static void Main()
    {
        using (IUnityContainer container = new UnityContainer())
        {
            container.RegisterType<ISecurityRepository, SecurityRepository>()
                     .RegisterType<ISecurityService, SecurityService>();

            MyClassThatNeedsSecurity myClass =
                container.Resolve<MyClassThatNeedsSecurity>();
        }
    }
}

This will print:

SecurityRepository created
SecurityService created
Repository is A SecurityRepository
My class has security: A SecurityService

You have a number of options, such as pre-creating your instances (as you showed in your follow-up post) or extending the lifetime of injected dependencies so that they're not recreated every time they're needed. But for the base case, this will work.

like image 156
TrueWill Avatar answered Oct 04 '22 07:10

TrueWill


here is some more information. The constructor of my class is

    public SecurityService(ISecurityRepository repository)
        : base(repository)
    {

    }

After playing around a little bit, i managed to do the following but this causes me to create instances FIRST ... It seems to work.., but its an alternative.

        // Create unity container my service and repository
        ISecurityRepository securityRepository = new SecurityRepository();
        ISecurityService securityService = new SecurityService(securityRepository);

        container = new UnityContainer();
        container.RegisterInstance<ISecurityRepository>(securityRepository);
        container.RegisterInstance<ISecurityService>(securityService);
like image 44
mark smith Avatar answered Oct 04 '22 08:10

mark smith