开发者

IOC Container build in code vs configuration.Advice needed

开发者 https://www.devze.com 2023-03-10 14:56 出处:网络
I have not done much IOC but from what I read and the examples I see on the internet it has confused me.

I have not done much IOC but from what I read and the examples I see on the internet it has confused me.

My understanding is that you should use IOC to promote loosely coupled system.

Now building the container in code (Unity) the one my company uses how can this be decoupled if I have to have a hard reference to my service EG

   IUnityContainer container=new Unit开发者_如何学GoyContainer()
    .RegisterType<IMyService,MyService>();

As you can see MyService is a concrete class which will require me to have a reference to my service layer.

Am I not defeating the point now?

Any examples or suggestions or views very welcome


Container is helping you build loosely coupled applications, but loosely coupled doesn't mean "no hard references on other assemblies" as you seem to be suggesting.

Interface and class that implements it may live in the same assembly, in the same namespace, event in the same .cs file, and that has nothing to do with loose or tight coupling.

It's about the classes that use other types depending on abstractions, not on concrete implementations. The fact that your registration code has knowledge of both, abstraction and concrete implementation is ok. After all you need to have some coupling.

In terms of mechanics, you can simplify the registration and not mention both types each time, and even not have reference to other assemblies by using conventions in some other containers like Windsor (Unity doesn't support convention-based registration to the best of my knowledge).

Again - this is mechanics and has nothing to do with loose vs tight coupling or reasons for using containers. It just makes using the container simpler.

HTH


Taking an example of an MVC app, the configuration

UnityContainer container = new UnityContainer()
    .RegisterType<IMyService, MyService>();

would be created when the application starts, and the benefits come when you use IMyService in, for example, a controller:

public class MyController : Controller
{
    private readonly IMyService _myService;

    public MyController(IMyService myService)
    {
        _myService = myService;
    } 

    public ActionResults Index()
    {
        var model = _myService.GetModel();
        return View(model);
    }
}

Compare this to a system that uses it this way:

public ActionResults Index()
{
    var model = new MyService().GetModel();
    return View(model);
}

Now you're married to that implementation. Unit testing becomes very difficult now as there's no way to mock IMyService.


The main concept at work, when you build up your IoC container through code, is that of Instability. Instability is a metric for Object-Oriented systems measuring the ratio of Efferent coupling to total coupling. It is most useful when applied at the "deployment package" level - which for .NET is the assembly.

When using this metric, the goal is not to achieve low Instability all of the time, but but rather to increase the Stablility of some assemblies (close to 0 Efferent coupling) by aggregating the Instability into other assemblies.

Depending on the platform you are working with, your .Exe (or the assembly containing your HttpApplication, ServiceHost, etc.) should assume the responsibility of managing Application startup, Application shutdown, and aggregation of all of the dependencies including building up your IoC (this will make it easier during deployment since the basic deployment scenario requires that your runtime project references any dependencies).

It is possible to configure your IoC using configuration files, thus saving your main application from potentially huge amounts of coupling, but the tradeoffs are as follows:

  • You lose the ability of manually building up an instance (perhaps performing some initialization that would be difficult through config) before registering the instance to be resolved against its interface.
  • Build checks - for instance mistyping the Class name or Interface name.
  • Ease of deployment. If you are not referencing the assemblies containing the interface implementations in your main project, you will have to manually deploy them or manually add them to your setup project (if you are using one). This may be more or less of a problem depending on the environment and any existing deployment processes that may be in place.
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号