Windsor container restriction on object-based resolution

I would like to create a container where it will allow ISomeService, but not ISomeOtherService. Although my registration for ISomeService is dependent on ISomeOtherService.

It makes sense?

public interface ISomeService {}

public interface ISomeOtherService {}

public class SomeService : ISomeService
{
    public SomeService(ISomeOtherService someOtherService) {}
}
public class SomeOtherService : ISomeOtherService {}

this container that I would like to allow SomeService for ISomeService, but if I tried to enable ISomeOtherService or SomeOtherService, it would fail.

Is this a bad design?

So, a little context ... I have ASP.Net MVC Controllers that will be developed by various developers. These controllers MUST have access to application services, such as ISomeService, but not to their dependencies. I would like you to not have to review all these services so that developers do not violate the design of the architecture. They should be able to get links to ISomeService, but ISomeOtherService is the database repository, and they should never deal with it directly, but ISomeService really needs this link.

( ASP.NET MVC, ), , , , , . , , ?

+4
3

SubDependencyResolver. . :

public class SubDependencyResolver : ISubDependencyResolver
{
    public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model,
                           DependencyModel dependency)
    {
        // If not an ISomeotherComponent or SomeOtherComponent is resolved ignore.
        if (dependency.TargetType != typeof (ISomeOtherComponent) && dependency.TargetType != typeof (SomeOtherComponent)) return false;

        // check if we are resolving for SomeComponent
        if (model.Implementation == typeof (SomeComponent)) return false;

        // We are resolving for a different component then SomeComponent.
        Debug.Assert(false);
        return false;
    }

    public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model,
                          DependencyModel dependency)
    {
        // We will never actually resolve the component, but always use the standard SubDependencyResolver, as Can resolve always returns false;
        return null;
    }
}


class Program
{
    static void Main(string[] args)
    {
        var container = new WindsorContainer();
        container.Kernel.Resolver.AddSubResolver(new SubDependencyResolver());
        container.Register(
            Component.For<ISomeOtherComponent>().ImplementedBy<SomeOtherComponent>(),
            Component.For<ISomeComponent>().ImplementedBy<SomeComponent>(),
            Component.For<Legal>()
//          Component.For<Illegal>() uncommenting this line will assert.
            );
    }
} 

public interface ISomeComponent
{
}

public interface ISomeOtherComponent
{
}

public class SomeComponent : ISomeComponent
{
    public SomeComponent(ISomeOtherComponent someOtherComponent)
    {
    }
}

public class SomeOtherComponent : ISomeOtherComponent
{
}

public class Legal
{
    public Legal(ISomeComponent component)
    {
    }
}

public class Illegal
{
    public Illegal(ISomeOtherComponent component)
    {
    }
}
+3

, , . ISomeService, ISomeOtherService - , , ISomeService .

, "WebUI" DataAccess :

, tre WebUI, ApplicationServices, DataAcccess.

WebUI ( ) ApplicationServices, ApplicationServices DataAcccess. , WebUI DataAcccess, instatnce WebUI.

WebUI:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var service = new ApplicationServices.SomeService();
        service.DoSmth();

        return View();
    }
}

ApplicationServices:

public class SomeService : ISomeService
{
    private readonly ISomeOtherService someOtherService;

    public SomeService() : this(new SomeOtherService())
    {

    }

    public SomeService(ISomeOtherService someOtherService)
    {
        this.someOtherService = someOtherService;
    }

    public void DoSmth()
    {
        someOtherService.DoDbCall();
    }
}

public interface ISomeService
{
    void DoSmth();
}

DataAcccess:

public class SomeOtherService : ISomeOtherService
{
    public void DoDbCall()
    {
        /* Db Calls */
    }
}

public interface ISomeOtherService
{
    void DoDbCall();
}

DataAcccess ther installers ApplicationServices.

+1

Windsor, UseFactoryMethod, , .

, Disallowed , , . , , Windsor.

class Program
{
    static void Main(string[] args)
    {

        try
        {
            var container = new Castle.Windsor.WindsorContainer();

            container.Register
            (
                Component
                .For<Restricted>()
                .UsingFactoryMethod
                (
                    (k, c) =>
                    {
                        var requestingType = c.Handler.ComponentModel.Implementation;
                        if (requestingType == typeof(Allowed))
                        {
                            return new RestrictedImp();
                        }
                        else
                        {
                            var errorMessage = string.Format
                            (
                                "The type [{0}] is not permitted to resolve [{1}].", 
                                requestingType.Name, 
                                c.RequestedType.Name
                            );
                            throw new InvalidOperationException(errorMessage);
                        }
                    }
                )
                .LifeStyle
                .Transient
            );
            container.Register(Component.For<Allowed>());
            container.Register(Component.For<Disallowed>());

            var a = container.Resolve<Allowed>();
            var b = container.Resolve<Disallowed>();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }

        Console.ReadLine();
    }
}

interface Restricted { }

class RestrictedImp : Restricted
{

}

class Allowed
{
    public Allowed(Restricted restricted)
    {

    }
}

class Disallowed
{
    public Disallowed(Restricted restricted)
    {

    }
}

, , Castle Windsor, , - Ninject Bind<T>.ToMethod(blah), , . -, , , . .

0
source

All Articles