ipjohnson / Grace

Grace is a feature rich dependency injection container library
MIT License
336 stars 33 forks source link

How to solve this scenario? Mixed locate strategy #202

Closed SuperJMN closed 5 years ago

SuperJMN commented 5 years ago

I have an object like this

class MyObject
{
    MyObject(string a, string b, ISomeService service) { }
}

Given: A dependency ISomeService that can be resolved (it's registrated withing the container) and a, b that ARE NOT registrated, When: container.Locate<MyObject>() is called Then: I would like Grace to ask me to resolve a and b myself.

In other words, I want that the container resolves as much as it could, but ask me for the values he couldn't resolve to resolve them manually.

Is that possible?

ipjohnson commented 5 years ago

Hi @SuperJMN ,

Yes you should be able to call container.Locate<MyObject>(new { a = "someString", b = "otherString"} );

You can also have some other options if you don't want to pass in a,b while calling Locate.

SuperJMN commented 5 years ago

Great! can you just provide the strings ordinally? I mean, implicitly saying "a = 1st string" and "b = 2nd string".

For instance:

var parameters = new [] { "value1", "value2";
container.Locate<MyObject>(parameters);
ipjohnson commented 5 years ago

At this point it does not support it that way. You can unnamed parameters but it’s just going to match the first on.

Is this something you need? Because I think it would be possible to write some custom code to support it. Though I do worry about how brittle things become when you’re calling constructors based on ordinal position

SuperJMN commented 5 years ago

Oh, no problem. I have created an abstraction to do the job.

I've created an little interpreter that executes things from a script. Each action can have very simple parameters, that are basically strings and ints.

The actions declare the dependencies in the ctor. There may be string and int dependencies, for example, for a Copy a to b action

public class CopyOperation(string source, string destination) : IDeploymentOperation 
{
     public Task Execute() 
     {
       …
     }
}

The interpreter takes the name of each action an creates an instance via reflection, taking the parameters from the script (strings and ints) and injecting the additional dependencies via Grace :)

That's how I'm doing it right now.

I've decided that it's better to use Grace for what's is good! and leave the custom logic to my abstraction. I asked you because I thought it could have this already bundled, because it's really flexible!

BTW, I think you remember me. I remember you, my friend! It's been long :D

I hope you're doing fine!

ipjohnson commented 5 years ago

@SuperJMN very good to see you. Drop me a line to say hi and we can catch up.