5

I am beginning to learn about the Unity Container and Dependency Injection. I'm having difficulty understanding what my object model should look like.

For my example, I created a really simple Employee class (I've omitted the Constructor, because that's what I'm confused about):

public class Employee
{
    private int _id;
    private string _name;
    private DateTime _birthDate;

    public int Id
    {
        get { return _id; }
    }

    public string Name
    {
        get { return _name; }
    }

    public DateTime BirthDate
    {
        get { return _birthDate; }
    }
}

This Employee object should get its information from a database. Here is a shim database adapter, just to develop a dependency:

public class DataAdapter
{
    public DbParameter NewParameter(string name, object value)
    {
        return new OracleParameter(name, value);
    }

    public DataRow ExecuteDataRow(string command, CommandType commandType, List<DbParameter> parameters)
    {
        DataTable dt = new DataTable();

        dt.Columns.Add(new DataColumn("ID"));
        dt.Columns.Add(new DataColumn("NAME"));
        dt.Columns.Add(new DataColumn("BIRTH_DATE"));

        DataRow dr = dt.NewRow();

        dr["ID"] = new Random().Next();
        dr["NAME"] = "John Smith";
        dr["BIRTH_DATE"] = DateTime.Now;

        return dr;
    }
}

Ideally, the employee object should take an "id" parameter in order to know which Employee to retrieve from the database. Let's say that we use an Employee constructor that looks like this:

public Employee(int id, DataAdapter dataAdapter)
{
    List<DbParameter> parameters = new List<DbParameter>();

    parameters.Add(dataAdapter.NewParameter("ID", id));

    DataRow dr = dataAdapter.ExecuteDataRow("GetEmployee", CommandType.StoredProcedure, parameters);

    if (dr == null)
        throw new EmployeeNotFoundException();

    _id = id;
    _name = Convert.ToString(dr["NAME"]);
    _birthDate = Convert.ToDateTime(dr["BIRTH_DATE"]);

    _id = employeeData.Id;
    _name = employeeData.Name;
    _birthDate = employeeData.BirthDate;
}

I'm not sure how to specify the Employee's id with Unity's resolver except using ParameterOverride:

class Program
{
    static void Main(string[] args)
    {
        UnityContainer container = new UnityContainer();

        container.RegisterType(typeof(EmployeeData));

        Employee emp = container.Resolve<Employee>(new ParameterOverride("id", 45));

        Console.WriteLine(emp.Id);
        Console.WriteLine(emp.Name);
        Console.WriteLine(emp.BirthDate);
        Console.ReadKey();
    }
}

I don't like this because there is no compile-time checking to see if the parameter name is correct. Problems like this make me think that I'm applying the pattern incorrectly. Can anybody shed some light on what I am misunderstanding?

Thanks!

2 Answers 2

6

Dependency Injection is not intended to be used on domain models / business objects. It's mainly to resolve services, i.e. classes which are used to process business logic.

Hence your persons are normally loaded using a repository or any other data access pattern.

So:

  1. Your data access class is injected using DI
  2. Your data access class acts as a factory and generates the person.

something like

public class PersonRepository
{
    public PersonRepository(IDbConnection iGetInjected)
    {
    }

    public Person Get(int id)
    {
        // I create and return a person
        // using the connection to generate and execute a command
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Ah, okay, I was trying to avoid using the Factory pattern because I thought that they were somewhat mutually exclusive, but I guess they're complementary after all. Thanks for your help!
0

You are using this pattern incorrectly. DI is about injecting dependencies, mainly throught interfaces.

Your code should look like this:

the interface

public interface IEmployee
{
    int Id { get; set;}
    string name { get; set;}
    DateTime BirthDate { get; set; }
}

and implementation

public class Employee : IEmployee
{
    public int Id { get; set;}
    public string name { get; set;}
    public DateTime BirthDate { get; set; }
}

then you can resolve the dependency through:

class Program
{
    static void Main(string[] args)
    {
        UnityContainer container = new UnityContainer();

        container.RegisterType(typeof(IEmployee), typeof(Employee));

        IEmployee emp = container.Resolve<IEmployee>();

        Console.ReadKey();
    }
}

Now you can use different implementations of IEmployee interface depending on your needs.

1 Comment

I didn't downvote you, but I suspect it was because you didn't explain how to resolve the "id constructor parameter" portion of my question. Thanks for your reply though!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.