views:

859

answers:

6

Hey everyone..

Trying to make use of the Castle Windsor IoC. I have a very simple application. My interfaces exist in Test.Services namespace. I get the following exception when compiling:

"The type name Test.Services.IParse, Test.Services could not be located"

This is my app.config:

<configuration>
  <configSections>
    <section name="castle"
      type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler,    
      Castle.Windsor" />


   </configSections>

  <castle>
    <components>
      <component id="HtmlTitleRetriever"
                 type="Test.HTMLTitleRetriever, Test">
      </component>
      <component id="FileParser"
                 service="Test.Services.IParse, Test.Services"
                 type="Test.FileParser,   
                      Test">
      </component>
      <component id="FileDownloader"
                 service="Test.Services.IDownload, Test.Services"
                 type="Test.FileDownloader, Test">
      </component>
    </components>
  </castle>

Can someone tell me what I'm missing?

Thanks

-Nick

A: 
IWindsorContainer container = new WindsorContainer();

        container.AddComponent("FileDownlader", typeof(IDownload),
             typeof(FileDownloader));
        container.AddComponent("FileParser", typeof(IParse),
             typeof(FileParser));
        container.AddComponent("HTMLTitleRetriever", typeof(HTMLTitleRetriever));

        HTMLTitleRetriever retriever = container.Resolve<HTMLTitleRetriever>();

Doing the following in code works. I would like to use a Config file though so changes do not need to be recompiled each time.

Doing the following in code works, because now you have hard dependency on all assemblies and compiler ensures they are accessible. My question still stands - do you copy the Test.Services.dll to the output directory when using config file? Notice that the compiler will not do that for you.
Krzysztof Koźmic
A: 

Almost Nick! You need to pass the xml configuration into the constructor of WindsorContainer:

IWindsorContainer container;
container =
  new WindsorContainer(
    new XmlInterpreter(
      new ConfigResource("castle")
  ));

I ran into this "Got ya" as well when I first started playing with Castle Windsor. It does not know to look into the configuration section.

Tip: go get the latest from their trunk. There's a new method called Register that is really useful for mass-registering multiple classes on the same interface. I.e., if you are developing with ASP.NET MVC, and you have a bunch of IController, you can use Castle Windsor to auto-register them for you. So, you do not have to specify them in the configuration file!

public class WindsorControllerFactory : IControllerFactor
{
  IWindsorContainer container;
  public WindsorControllerFactory()
  {
    container =
      new WindsorContainer(
        new XmlInterpreter(
          new ConfigResource("castleWindsor")
      ));

    container.Register(
      AllTypes.Of<IController>()
      .FromAssembly(Assembly.GetExecutingAssembly())
      .Configure(component => component.LifeStyle.Transient
        .Named(component.Implementation.Name)
      ));
  }
}
eduncan911
IWindsorContainer container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));I tried this.. Same issue. I am checking the obviouse and I see no typos. "Cannot find the type Test.Services.IParse"
Could you update your question with actual code? You have to ensure your namespaces and assembly names are correct.
eduncan911
A: 

Same thing... finding the configuration doesn't seem to be the problem. It's as if it cannot find this namespace. I have checked and I see no typos?!

It will have to be a namespace-ing issue; and/or, it could be the actual assembly name incorrect for the project assembly being created. You specify the assembly name to be "Test.dll" for the implementation of the class. Is that the name of the assembly when you compile?
eduncan911
+1  A: 

Stupid question, but are you certain that the assembly containing the class you register gets actually copied to the output directory?

Krzysztof Koźmic
It's not a stupid question at all. It can easily be done, if you don't have a reference to the assembly containing your service then it won't exist in the output folder.
Antony Scott
I know. I'm just making sure :)
Krzysztof Koźmic
A: 

Is the IParse interface in the Test.Services assembly (Test.Services.dll) ?

The format used to define type names in the config is the same you can get from the AssemblyQualifiedName property of the type. In a nutshell, it's:

Namespace.Type, Assembly.

For generic types, see this.

Mauricio Scheffer
A: 

I had the same issue and Eric's solution worked to resolve the problem. I Created a "Domain Models" Project and then later renamed it to "DomainModel" I though I changed all the references but then looking in the bin folder the assembly was still called "Domain Models" thats why castle windsor could not find it.

Cool. :) (Name is now eduncan911, not Eric)
eduncan911