A Nuget Packaging Dilemma

26 commentsWritten on March 27th, 2011 by
Categories: agatha

I've been thinking about how Agatha should be packaged for Nuget and i just can't come up with something that i like. The problem is that Nuget misses a concept that is necessary for packages which depend on one of many possible dependencies. Agatha requires an Inversion Of Control container, but it allows you to use the container you prefer. I've talked before about the loyalty that many of us show to our preferred container, and i'm pretty sure that forcing users to use a specific container would severely limit the number of possible users Agatha could attract. So right now, Agatha users need to pick which container they want to use.

Now how do you make that fit into the Nuget packaging system? Ideally, Nuget would someday support a scenario where i can define that my package requires the user to also select one package from a list of suitable packages but until that's possible i can't really come up with a solution that i like. Here's what i specifically don't want:

  • I don't want the package to include something that the user might not want.
  • I don't want to force a particular container on users
  • I don't want to ILMerge any container assemblies because that would cause problems if users themselves make use of a container already.
  • I don't want to do it like the current NHibernate 3.1 package because that pretty much guarantees nobody will install it. NHibernate can get away with something like that because it's already an established project.

Ideally, i'd be able to define the following package structure:

  • Agatha-RRSL, requires one of the following packages to be installed (if no selection is made, go with Agatha-Windsor by default):
    • Agatha-Windsor, depends on Agatha-RRSL and Castle Windsor
    • Agatha-StructureMap, depends on Agatha-RRSL and StructureMap
    • Agatha-NInject, depends on Agatha-RRSL and NInject
    • ... (one for each supported container)

If that were possible, users wouldn't have to include anything they don't like and it could work together nicely with the packages of the various IOC containers.

As for how it should be packaged for now, i still have no idea. Suggestions are welcome :)

  • http://twitter.com/NotMyself Bobby Johnson

    I don’t know if it will work for Agatha but I really like the way that TopShelf handles this problem. They started out supporting Common Service Locator but then moved over to this method:

    https://gist.github.com/889342

    • http://davybrion.com Davy Brion

      CSL is not an option for me since i want to provide automatic registration/configuration out of the box… so registration of components is included in my container abstraction, which is missing from CSL

      not sure what the TopShelf example shows… how does that avoid the runtime-dependency on a particular container?

      • http://twitter.com/NotMyself Bobby Johnson

        the dependency is not in TopShelf it simply exposes a method that has to return an implementation of the service type. It is up to the consumer of top shelf to supply that implementation. So in the example, I new up a application container (Windsor) and when I am configuring TopShelf I use the container to provide the implementation of the service. TopShelf has no idea where it is coming from. Sorry if I wasn’t clear.

        • http://davybrion.com Davy Brion

          yeah Agatha does something similar… it requires you to either pass in a specific container instance, or at least specify which one you want. That’s what i mean with the runtime dependency… it’s only required at runtime, not compile-time. And since Agatha requires the IOC container for its internal usage as well, it’s something that you just have to provide.

  • http://www.zduck.com Joshua

    Obviously you could simply publish multiple Nuget packages. One for each IoC that Agatha supports. Ex. Agatha-Windsor, Agatha-StructureMap, Agatha-Ninject, etc.

    No, I don’t like this idea but it is a possible solution until Nuget adds support for this.

    • http://davybrion.com Davy Brion

      yup, that probably has the fewest drawbacks

    • http://twitter.com/dgoyani Dhananjay Goyani

      +1

  • http://twitter.com/ewhauser ewhauser

    Caliburn (http://caliburn.codeplex.com/) ships with a class called SimpleContainer that does a lot of things an IoC container provides. Not sure if it does everything you need from a container, but included a minimal container is one way to get around requiring the dependencies. That will let most users choose their container of choice as a separate package.

    • http://davybrion.com Davy Brion

      i just need the basics from a container, but providing (and having to maintain) a simple, default implementation is something i’m not willing to do to get around a packaging limitation while there are plenty of excellent containers available

  • http://twitter.com/fquednau Frank L. Quednau

    The download numbers of NH don’t necessarily suggest that nobody downloads it. I do think for such a situation it is is the correct way to do the packaging. How does rubygem handle this? Can you mark a package as “only installable as dependency of some other package”?

    • http://davybrion.com Davy Brion

      i don’t think it would be a good idea to explicitly mark it as such… a better alternative (IMO) would be to say: this package requires you to select one of the following plugins. That’s a simple, clear and correct description of the situation.

  • Bill Rohrbach

    Couldn’t you have a Powershell script as part of the NuGet package that would inspect the current project for existing IoC containers and then bring in the appropriate container based on that? And then fall back to a default if you don’t find one. I believe the MvcScaffolding does something similar in terms of tieing to the appropriate view engine based on looking at what types of view files are in the project.

  • whoever

    Not sure if this is the right place to ask, but here it is:

    So the Agatha RRSL service WSDL is just an array of Request? Is there a way to make them more explicit? I’d love the convenient specially when sharing a common assembly, but I’m going to have a hard time justifying it. Thanks.

    • http://davybrion.com Davy Brion

      you can read more on Agatha in my blog series about RRSL and on the project’s page:
      http://davybrion.com/blog/2009/11/requestresponse-service-layer-series/
      http://code.google.com/p/agatha-rrsl/

      • whoever

        Thanks. I did read all the rrsl related blogs and setup and adapt it to work in my own project. Although admittedly not at the source code level and fully understand the entire architecture, so I could have missed something important. The problem I have is, even though we are mostly a Microsoft shop, we have kind of informal standard of testing a service using soapUI. Since rrsl service is an array of requests, it’s not quite clear how that can be done. Also, is there a way I can document and publish my service without having to look into the handler classes?

        • http://davybrion.com Davy Brion

          ah ok, sorry about that :)

          All Request and Response derived types are added to the WSDL because they’re automatically added as KnownTypes of Request and Response. I don’t have enough SoapUI experience to claim whether or not it should work, but i guess it depends on how well SoapUI deals with known types…

          But everything is in the WSDL, so you can certainly publish your service without having to list your handler classes or anything like that

          • whoever

            Thanks. It looks better and better now. One more if I haven’t bored you completely with stupid questions:

            I’m trying to make a asp.web application calling the service. I got an object null reference when trying

            requestDispatcher = IoC.Container.Resolve[IRequestDispatcher]();

            Where should I do this in an asp.net application? Thanks

          • whoever

            Hi, I realize it has something to do with initialize. So in a asp.net web application, how do I do this?

            new ClientConfiguration(typeof(HelloWorldRequest).Assembly, typeof(Agatha.Spring.Container)).Initialize();

            - I should do the client configuration, right? And the service host initialize the serviceconfiguration through ComponentRegistration.Register()?

            - Do I need to do this for every Request/Response that needs to be called? Your example only initialize HelloWorldRequest, but the json example calls multiples, not sure if I missed anything here.

            - Where should initialization happens? I got some errors when trying to do this in page, it seems fine in application_start, is that the right place?

            - After doing this, I still got an error resovling IRequestDispatcher.

            Error creating object with name ‘Agatha.Common.IRequestDispatcher’ : Unsatisfied dependency expressed through constructor argument with index 0 of type [Agatha.Common.IRequestProcessor] : Error creating object with name ‘Agatha.Common.IRequestProcessor’ : Initialization of object failed : Cannot instantiate Type [Agatha.Common.WCF.RequestProcessorProxy] using ctor [Void .ctor()] : ‘Could not find default endpoint element that references contract ‘Agatha.Common.WCF.IWcfRequestProcessor’ in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.’

            Really appreciate your help. Thanks.

            • http://davybrion.com Davy Brion

              the clientconfiguration definitely needs to be done… i usually do this in application_start

              you don’t need to do it for every request/response type… just pass in the type of one and it will automatically register all of the request/response types within the same assembly as the type you passed in. If you have request/response types in multiple assemblies then you have to add them for each assembly (there are overloads for this)

              as for the error you got: did you add the WCF configuration to the config file of your host project?

              you’re usually better off asking questions (or searching the previously asked questions) on the agatha discussion group: http://groups.google.com/group/agatha-rrsl

              • whoever

                Eureka! Time to go back and re-read all your articles and let the fun begin! Will bother you later on the group, with questions hopefully not as stupid ^_^

  • http://twitter.com/mausch Mauricio Scheffer

    For SolrNet I provide a stand-alone SolrNet package (which uses a built-in basic container, lots of people don’t know or care about IoC), then a separate SolrNet.Windsor package, SolrNet.Ninject, SolrNet.StructureMap, etc. I wouldn’t say this is an issue with NuGet or packages, I had this separation way before any package solutions came out. It’s just a way of managing optional dependencies…

    • http://davybrion.com Davy Brion

      i don’t doubt that many people don’t care about IoC, but that’s not a valid reason for me to reinvent the wheel

      • http://twitter.com/mausch Mauricio Scheffer

        I have lots of SolrNet users that don’t want to be bothered with IoC. They just want to “new up the thing” and use it, so I provide something as close as possible to that. About reinventing the wheel… I thought about this as well, but a basic container is very easy to do, 150 LoC tops.

  • sinful bikinis

    At present reality be informed there a fabulous amount as well as mixture in feasible options on occupation bralilian bikinis design. layout comprise of mastectomy bralilian bikinis, maternal bralilian bikinis, fluid cardiovascular bodily exercise accents, energy as well as the sunlight completely clean bralilian bikinis, wetsuits, sporting bralilian bikinis, and measured bralilian bikinis, amplified customized bralilian bikinis and that sizeable many different sorts of womens as well when you is going to be capable bralilian bikinis.Mastectomy bralilian bikinis is without any a doubt extraordinary bralilian bikinis you’ll need for grownup females that completely have possessed an essential chest enlargement deleted. That bralilian bikinis is recognized for just about any extraordinary back again pocket attached toward produce the chest enlargement prosthesis it affliction shorts is in area to the period of your time of possibly even burberry bikinis uk instead possibly probably the most rock reliable in fun-based activities. That bikinis consist of the quantity of layout affliction short pants consist of troubles like choose to affordable and amplified necklines, great and small protected as well as skirted and saronged adaptations burberry swim shorts as well as pace settings feasible options definitely are generally not restrained. A vital panic attacks in among many different grownup females is without any a doubt the actuality the fact that chest enlargement adaptations can have make contact with with chlorine like a end result of cooling away and heats like a end result of sunbathing, cheap burberry swimsuit producer names are in contract this could possibly not authentic. Some other panic attacks is without any a doubt the actuality the fact that whole body body fat belonging to the prosthesis could possibly just be overweight for just Aff short pants about any solitary affliction swimwear match. That swimming costumes made burberry swim bikini currently could be in particular produced with that Affliction beach shorts powerful sewing burberry bikini top as well as precise components to confirm not alone level of comfort but possibly product of your head.
      var _gaq = _gaq || [];  _gaq.push(['_setAccount', 'UA-13121660-3']);  _gaq.push(['_trackPageview']);
      (function() {    var ga = document.createElement(‘script’); ga.type = ‘text/javascript’; ga.async = true;    Christian Audigier swimwear  ga.src = (‘https:’ == document.location.protocol ? ‘https://ssl‘ : ‘http://www‘) + ‘.google-analytics.com/ga.js’;    var s = document.getElementsByTagName(‘script’)[0]; s.parentNode.insertBefore(ga, s);  })();
     

  • Pingback: Agatha 1.3 Is Out

  • Rebakhshan

    at sending data type’s fileStraem and DataTable  from service layer to client occurred this erorr [System.ServiceModel.CommunicationException]
    but with data type’s string or integer worked correctly.
    pleas help me to resolve this problem

    //my Source dode is:

    //Common File
    public class YIPDataResponse : Response {public System.IO.Stream FileByteStream{ get; set; }}//the part of service Layer that return streamswitch(RequestType){case “PR”: response.FileByteStream = Proclamation(Ver); break;}(RequestType){
    case “PR”: response.FileByteStream = Proclamation(Ver); break;}case “PR”: response.FileByteStream = Proclamation(Ver); break;} class YIPDataResponse : Response {
    public System.IO.Stream FileByteStream{ get; set; }}//the part of service Layer that return streamswitch(RequestType){case “PR”: response.FileByteStream = Proclamation(Ver); break;}(RequestType){
    case “PR”: response.FileByteStream = Proclamation(Ver); break;}case “PR”: response.FileByteStream = Proclamation(Ver); break;}

    public System.IO.Stream FileByteStream{ get; set; }}//the part of service Layer that return streamswitch(RequestType){case “PR”: response.FileByteStream = Proclamation(Ver); break;}(RequestType){
    case “PR”: response.FileByteStream = Proclamation(Ver); break;}case “PR”: response.FileByteStream = Proclamation(Ver); break;}