views:

252

answers:

5

Hi guys I have a dependency that I need to inject into one of my classes. This dependency will be lifestyle of Transient. It inturn has a dependency of type Type. This type should be the type of the original class. I was just wondering if anyone has any idea how I might go about conducting this registration.

See example:

public interface ICustomer
{
    .....
}

public class Customer : ICustomer
{
    public Customer(IRegister register)
    { .... }
}

public interface IRegister
{
    .....
}

public class Register
{
    public Register(Type partentType)
    { .... }
}

public class TestExample
{
    public static void TestMe()
    {
        //If i was creating all this manually it would look
        //   something like this
        IRegister myRegister = new Register(typeof(Customer));
        ICustomer myCustomer = new Customer(myRegister);
    }
}

Now i know i could call Container.Resolve when ever I want a Customer and then inject Register manually. But I need to inject Register into most of my classes so this isn't really that feasible. Hence I need a way of doing it via the config or via container.Register.

Cheers Anthony

A: 

I'm not entirely sure it is that you're trying to achieve, but instead you might want to rewrite your code so you're doing:

public interface IRegister{
    RegisterResult MyMethod(object thing);
}

So you pass the instance into the register, that way you don't need to pass the type into the constructor and you can still use your DI container. I hope this makes sense...

jonnii
A: 

I thought of that but it would mean the parent object would need to know about this little implementation quirk. Hence I would be creating a dependency which i could no longer enforce. Do you see that as an issue?

As far as what I am trying to achieve, the Register needs to have the type of the parent class in order for it to do its work. Hence it is a mandatory dependency. If it wasn't mandatory I would just have a property that I would set. I know i could use reflection but for performance reasons I am trying to avoid that.

The other alternative is that when at the top of the customer constructor, I set the type on the Registry class (via a public property). But again this implementation quirk that the person using Register would need to know about, not one that i could enforce.

Cheers Anthony

vdhant
A: 

What is it exactly that the register does? Does the customer object ever use the register internally?

I don't know which DI container you're using, but assuming you were using Windsor you could have a custom facility to intercept any component creation and then do your interaction with your register there. That way you wouldn't even have to have the customer class take the register as a parameter.

jonnii
A: 

The simplest solution I can see is to change it to

public interface IRegister<TParent> { ... }
public class Register<TParent> : IRegister<TParent>
{
    public Register() { ... }
}

public class Customer : ICustomer
{
    public Customer(IRegister<Customer> register) { .... }
}

And register IRegister as an open generic class.

Andrey Shchekin
+1  A: 

ICustomer is setting off alarm bells in my head. Unless you can show me at least two other real implementations of ICustomer, mocks don't count, you have a flaw in your design.

Jonathan Allen