I registered
container.RegisterType<IService, MyService>();
I want to create a helper class similar to
public class MyHelper
{
private IService _service;
public void SomeMethod
{
_service.RunSomething();
}
}
I really wish this _serivce just magically maps to MyService constructor and not be null, as I have no where to find an IService or Service instance anywhere else.
How can I make this _service self mapped according to Unity mapping?
You still have to assign the injected IService
to your instance. This is usually done via the constructor:
public class MyHelper {
private readonly IService _service;
public MyHelper(IService service) {
_service = service;
}
public void SomeMethod() {
// _service isn't null anymore
}
}
Edit: looking at your comment I don't think you're using IoC correctly so I'm going to try to fill in some gaps. You don't want to create new instances of MyHelper
beacuse whatever creates it will have to have knowledge of IService
and any other dependencies MyHelper
introduces. Instead, you can create a factory that handles creating new instances of MyHelper
which will also handle its dependencies. This way, you can set up IoC to resolve dependencies on this factory.
public interface IInstanceFactory<out T> {
T Create();
}
public class MyHelperFactory : IInstanceFactory<MyHelper> {
private readonly Func<MyHelper> _myHelperFactory;
public MyHelperFactory(Func<MyHelper> myHelperFactory) {
_myHelperFactory = myHelperFactory;
}
public MyHelper Create() {
return _myHelperFactory();
}
}
So we now have a factory that stores a Func
which is used to create an instance of MyHelper
. All it's doing is executing the function that we will define in the IoC setup. All that function does is return a new instance of MyHelper
.
Now we can set up IoC to handle everything else for us. So in your IoC setup you'd do the following (I don't know Unity so I'm going to show you using Autofac. Unity should be capable of doing everything I'm showing.)
Register the service:
container.RegisterType<MyService>().As<IService>();
Register the factory: (this is where the magic happens)
container.Resolve(b => {
var service = b.Resolve<IService>();
var myHelperFactory = new Func<MyHelper>(() => new MyHelper(service));
return new MyHelperFactory(myHelperFactory);
}).As<IInstanceFactory<MyHelper>>();
Here we get an instance of IService
which we already registered as MyService
. Then we create a Func<MyHelper>
who just creates a new instance of MyHelper
and passes along the IService
instance we just resolved. Lastly, we return a new MyHelperFactory
and pass the Func<MyHelper>
into the factory.
So lets say we have the class Foo
. And Foo
needs to create an instance of MyHelper
without having any knowledge of MyHelper's
dependencies:
public class Foo {
private readonly IMyHelperFactory _factory;
public Foo(IMyHelperFactory factory) {
_factory = factory;
}
public void MethodThatCreatesMyHelper() {
var instance = _factory.Create();
// you now have a valid instance of `MyHelper`
}
}
The last thing you would do is resolve Foo
from your container (as long as you set it up):
var fooInstance = container.Resolve<Foo>();
fooInstance.MethodThatCreatesMyHelper();
And here is a gist of my example above. The point to take away is that Foo
can create an instance MyHelper
without having any knowledge of its dependencies.
One technique is to initialize MyHelper
with an object that builds an IService
object in the constructor. This can be as simple as a lambda expession:
public class MyHelper : IMyHelper
{
private Func<IService> _serviceBuilderFunc;
public MyHelper(Func<IService> serviceBuilderFunc)
{
_serviceBuilderFunc = serviceBuilderFunc;
}
public void SomeMethod()
{
var svc = _serviceBuilderFunc();
svc.RunSomething();
}
}
Then in your unity container configuration use the overload of RegisterType()
to specify constructor parameters:
var serviceBuilderFunc = () => new MyService();
container.RegisterType<IMyHelper, MyHelper>(
new InjectionConstructor(serviceBuilderFunc));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.