I do not understand the error I am getting as listed at the bottom of this question. Why is the container trying to cast the object, especially if the compiler is doing it without error? I am using v2.0.0.5642.
I’m sure it’s in the configuration, but I am lost. I would really appreciate any help.
<component id="cipherMaster" type="Demo.View.UserControls.CipherMaster, Demo.View" />
<component id="cipherVariation" service="Demo.View.UserControls.CipherMaster, Demo.View"
type="Demo.View.UserControls.CipherVariation, Demo.View" />
<component id="presenterVariation" service="Demo.Model.Interfaces.IDemoTypePresenter, Demo.Model"
type="Demo.Presenter.PresenterVariation, Demo.Presenter" >
<cipherPanel>${cipherVariation}</cipherPanel>
</component>
namespace Demo.Presenter
{
public class PresenterCipherMaster : IDemoTypePresenter
{
...
}
}
namespace Demo.Presenter
{
public class PresenterVariation : PresenterCipherMaster
{
private readonly CipherVariation _variation;
public PresenterVariation(IMasterDemo view, CipherMaster cipherPanel, FeaturesVariation features,
IEncryptionEngine engine):base(view, cipherPanel, features, engine)
{
_variationLog = new List<CipherVariationLog>();
_variation = (CipherVariation) cipherPanel; //<<< Cast error points here line 18
...
}
}
}
public static class IocContainer
{
public static T Resolve<T>(string key)
{
T presenter = Container.Resolve<T>(key); //<<< Error occurs here
return presenter;
}
}
namespace Demo.View.UserControls
{
public partial class CipherMaster : UserControl
{
...
}
}
namespace Demo.View.UserControls
{
public partial class CipherVariation : CipherMaster
{
...
}
}
=====================
Castle.MicroKernel.ComponentActivator.ComponentActivatorException was unhandled
Message="ComponentActivator: could not instantiate Demo.Presenter.PresenterVariation"
Source="Castle.MicroKernel"
StackTrace:
...
InnerException: System.Reflection.TargetInvocationException
Message="Exception has been thrown by the target of an invocation."
Source="mscorlib"
StackTrace:
...
InnerException: System.InvalidCastException
Message="Unable to cast object of type 'Demo.View.UserControls.CipherMaster' to type 'Demo.View.UserControls.CipherVariation'."
Source="Demo.Presenter"
StackTrace:
at Demo.Presenter.PresenterVariation..ctor(IMasterDemo view, CipherMaster cipherPanel, FeaturesVariation features, IEncryptionEngine engine) in E:\Development\MainStreamDemo\Demo.Presenter\PresenterVariation.cs:line 18
InnerException:
I've seen situations where Castle resolves against the other registered services first, and then uses the parameters you specify. In this case since you are using a concrete type as the argument (CipherMaster) and it is registered, it's probably using the registered component.
I would try either creating an interface for the two controls to implement or just changing the type on the constructor to just "Object" or "UserControl" so that it's not a registered type.
Related
Most of my components are registered using the code-based (fluent) approach, but there is one particular component that I need to resolve differently at runtime. This is the interface and a couple of concrete implementations:-
public interface ICommsService ...
public class SerialCommsService : ICommsService ...
public class TcpCommsService : ICommsService ...
Some of our users will need the serial service while others will need the TCP service. My current solution (which works btw) is to use a typed factory and a custom component selector - the latter reads an app.config setting to determine which implementation the typed factory will resolve and return.
First the typed factory (nothing special about this):-
public interface ICommsServiceFactory
{
ICommsService Create();
void Release(ICommsService component);
}
Next, the custom component selector, which reads the fully-qualified type name from app.config (e.g. "MyApp.SomeNamespace.TcpCommsService"):-
public class CommsFactoryComponentSelector : DefaultTypedFactoryComponentSelector
{
protected override string GetComponentName(MethodInfo method, object[] arguments)
{
return ConfigurationManager.AppSettings["commsServiceType"];
}
}
Then the registration stuff:-
var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<ITypedFactoryComponentSelector>()
.ImplementedBy<CommsFactoryComponentSelector>());
container.Register(Component.For<ICommsFactory>()
.AsFactory(o => o.SelectedWith<CommsFactoryComponentSelector>()));
container.Register(Component.For<ICommsService>()
.ImplementedBy<SerialCommsService>().LifeStyle.Singleton);
container.Register(Component.For<ICommsService>()
.ImplementedBy<TcpCommsService>().LifeStyle.Singleton);
Finally, an example class with a dependency on ICommsService:-
public class Test
{
public Test(ICommsFactory commsFactory)
{
var commsService = commsFactory.Create();
...
}
}
As already mentioned, the above solution does work, but I don't like having to inject the factory. It would be more intuitive if I could just inject an ICommsService, and let something somewhere figure out which implementation to resolve and inject - similar to what I'm doing now but earlier in Windsor's "resolving pipeline". Is something like that possible?
You can use UsingFactoryMethod here:
container.Register(Component.For<ICommsService>().UsingFactoryMethod(kernel => kernel.Resolve<ICommsServiceFactory>().Create()));
You can inject ICommsService to any class now. ICommsServiceFactory can be a simple interface now:
interface ICommsServiceFactory
{
ICommsService Create();
}
I am in the processing of learning Kotlin and ran into a problem I couldn't figure out.
I would like to extend the Java class RuntimeException in Kotlin and be able to use any one of three of its constructors, in different circumstances (based on what info I have at the time I want to throw an exception). In java my class would look like this:
public class PhotoLibException extends RuntimeException {
public PhotoLibException(String message, RuntimeException ex) {
super(message, ex);
}
public PhotoLibException(String message) {
super(message);
}
public PhotoLibException(RuntimeException ex) {
super(ex);
}
}
When I try to do this in Kotlin, I used this answer as a guide: Kotlin secondary constructor however, I had a problem trying to figure out how to invoke the appropriate super constructor correctly. For example, using functions seemed to be a good approach, like this:
fun PhotoLibException(message: String): PhotoLibException {
val ex = null
return PhotoLibException(message, ex)
}
fun PhotoLibException(ex: Exception): PhotoLibException {
val message = ""
return PhotoLibException(message, ex)
}
class PhotoLibException(message: String, ex: Exception?): RuntimeException(message, ex) {
}
However, in this Kotlin example above, I am always invoking the super constructor with two args, and not invoking the constructor most appropriate to the situation. So what I have above works, but doesn't do exactly what it would do in Java where a different constructor is invoked in each situation.
I also tried instantiating a new RuntimeException inside each fun above and casting it to PhotoLibException, but I wasn't allowed to do that.
Can anyone suggest how I would do this correctly in Kotlin?
Update: Since M11 (0.11.*), you can use secondary constructors to solve this problem:
class PhotoLibException : RuntimeException {
constructor(message: String, ex: Exception?): super(message, ex) {}
constructor(message: String): super(message) {}
constructor(ex: Exception): super(ex) {}
}
Currently, there's no way to call different super-constructors in different context from the same class. It will be supported in the upcoming months, though.
Use the #JvmOverloads annotation.
class PhotoLibException: RuntimeException {
#JvmOverloads constructor(message: String, ex: Exception?)
}
all of the samples i've seen online with regard to custom parametersuppliers have something like:
List<PotentialAssignment> list = new ArrayList<PotentialAssignment>();
list.add(PotentialAssignment.forValue("teams", "giants"));
list.add(PotentialAssignment.forValue("teams", "jets"));
list.add(PotentialAssignment.forValue("teams", "niners"));
return list;
now, the question i have is: what does the first argument to PotentialAssignment.forValue(arg1, arg2) do? Nothing i've seen online has explained the significance of it.
thanks
The first parameter of PotentialAssignment.forValue is the "name" of the value. It is not used, if your #Theory method passes, but if it fails, it is used to assemble the error message. Here is an example:
#RunWith(Theories.class)
public class CustomParameterSupplierTest {
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.PARAMETER)
#ParametersSuppliedBy(FooSupplier.class)
public #interface Foo {}
public static class FooSupplier extends ParameterSupplier {
#Override
public List<PotentialAssignment> getValueSources(ParameterSignature sig) {
return Arrays.asList(
PotentialAssignment.forValue("one", 1),
PotentialAssignment.forValue("two", 2)
);
}
}
#Theory
public void test(#Foo int foo) {
assertThat(foo, is(1));
}
}
If this test is executed with Junit 4.11 you will get the following error:
org.junit.experimental.theories.internal.ParameterizedAssertionError: test(two)
By the way, in the upcoming release JUnit 4.12 the error reporting is further improved and you will get the following error:
org.junit.experimental.theories.internal.ParameterizedAssertionError: test("2" <from two>)
I have a seemingly simple use case. There is a ICsvReader component. Let's name it simply Reader here. We load a known set of CSV files and some of them have headers and some don't. Currently there are multiple readers: Reader_Skips1Row, Reader_Skips2Rows etc.
Is there a way to register only one component and have Windsor look at the component key, strip the "_Skips..." part and resolve the required component with relevant properties set?
I have tried subresolver and facility with no luck.
EDIT
Yes there is only one implementation but it is used as a dependency and configured to be resolved by name. The reader is configured in code
Component.For<ICsvReader>()
.ImplementedBy<CommaSeparetedCsvReader>()
.DependsOn(new { SkipHeader = true, HeaderRowsToSkip = 2 } )
.Named("CommaSeparetedCsvReader_Skips2Rows")
.Lifestyle.Transient
Component.For<ICsvReader>()
.ImplementedBy<CommaSeparetedCsvReader>()
.DependsOn(new { SkipHeader = true, HeaderRowsToSkip = 1 } )
.Named("CommaSeparetedCsvReader_Skips1Row")
.Lifestyle.Transient
Component.For<ICsvReader>()
.ImplementedBy<CommaSeparetedCsvReader>()
.Named("CommaSeparetedCsvReader")
.Lifestyle.Transient
These are used as dependency in a processor class. It is configured in XML, so that in can be manipulated at runtime
<component id="Processor
type="Processor">
<parameters>
<reader>CommaSeparetedCsvReader_Skips2Rows</reader>
</parameters>
</component>
Ideally I would like to register only the CommaSeparetedCsvReader component but when an attempt is made to resolve CommaSeparetedCsvReader_Skips2Rows it should strip the suffix, parse it and change the properties accordingly.
Is it possible to somehow modify the Resolve() behavior?
Thanks,
Tom
If you are resolving your components using the TypedFactoryFacility, creating a custom ITypedFactoryComponentSelectors might help you. I would need more detail on how you create the Readers to give you more info.
Kind regards,
Marwijn.
Edit =====================================
Let's add an example:
public interface IFoo
{
}
public class Foo1 : IFoo
{
}
public class Foo2 : IFoo
{
}
public interface IFooFactory
{
IFoo CreateFoo(string which);
}
public class FooFactoryComponentSelector : DefaultTypedFactoryComponentSelector
{
protected override string GetComponentName(MethodInfo method, object[] arguments)
{
return (string)arguments[0];
}
}
--- registration
container.AddFacility<TypedFactoryFacility>();
Component.For<IFoo>().Named("Foo1Name").ImplementedBy<Foo1>(),
Component.For<IFoo>().Named("Foo2Name").ImplementedBy<Foo2>(),
Component.For<IFooFactory>().AsFactory(f => f.SelectedWith(new FooFactoryComponentSelector())),
--- usage
var factory = _container.Resolve<IFooFactory>(); // in general this would just be a dependency in the constructor.
var foo = factory.CreateFoo("Foo2Name");
Just adapt the component selector to your needs. If necessary you can also pass additional arguments to CreateFoo, if the constructor requires arguments not provided by the container.
More info: http://docs.castleproject.org/Windsor.Typed-Factory-Facility-interface-based-factories.ashx
I am trying to build a application with several camel routes which re use many common routes internally.
Hence, I am trying to segregate the routes in several different Route Builder classes and then connecting the routes where needed.
For eg, all routes pertaining to sending emails go into a EmailRouteBuilder class and all routes dealing with a particular JMS Queue go into MyQueueRouteBuilder class.
I suppose this should be alright since Camel doesnt not distinguish between classes and only looks for routes defininition.
In addition, I am also grouping several exception handling routes into a separate ExceptionHandlingRouteBuilder.
I am also connecting all the different classes together by defining the camel context in Spring like so -
<camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring">
<propertyPlaceholder id="properties" location="classpath:${env}/autoimport.properties"/>
<!-- Common Routes -->
<routeBuilder ref="emailRouteBuilder" />
<routeBuilder ref="myQueueRouteBuilder" />
<routeBuilder ref="httpRouteBuilder" />
<routeBuilder ref="exceptionsRouteBuilder" />
<routeBuilder ref="customer1RouteBuilder" />
<routeBuilder ref="customer2RouteBuilder" />
</camelContext>
My exceptionsRouteBuilder contains many exception clauses like -
onException(ConnectException.class)
.routeId("connectExceptionEP")
.handled(true)
.log("Caught Exception: ")
.to("direct:gracefulExit");
..
..
..
However, it looks like there is a problem with the exceptions being defined in another class, or for that matter, defined separately out of the main route definition.
I verified this in the logs by looking for the routes being booted ( by routeId ) and also checking when an exception is thrown.
Additionally, to further confirm, I took the http Connect Exception handling route and put that directly in the httpRouteBuilder and lo..! , the exception handling now kicks in just fine for this exception..
Am I missing something here to get all exceptions to work while being nicely defined in its own class. ?
I am using Apache Camel 2.9.0 , but I verified the same behavior also in 2.8.3.
Thanks,
Anand
correct, the onException() clauses only apply to the current RouteBuilder's route definitions...
that said, you can reuse these definitions by having all your RouteBuilders extend the ExceptionRouteBuilder and call super.configure()...something like this
public class MyRouteBuilder extends ExceptionRouteBuilder {
#Override
public void configure() throws Exception {
super.configure();
from("direct:start").throwException(new Exception("error"));
}
}
...
public class ExceptionRouteBuilder implements RouteBuilder {
#Override
public void configure() throws Exception {
onException(Exception.class).handled(true).to("mock:error");
}
}
or even just have a static method in an ExceptionBuilder class to setup the clauses for a given RouteBuilder instance
public class MyRouteBuilder extends RouteBuilder {
#Override
public void configure() throws Exception {
ExceptionBuilder.setup(this);
from("direct:start").throwException(new Exception("error"));
}
}
...
public class ExceptionBuilder {
public static void setup(RouteBuilder routeBuilder) {
routeBuilder.onException(Exception.class).handled(true).to("mock:error");
}
}
Based on the accepted answer, I found a cleaner way to implement exception handling, so you don't have to call super.configure() in every route. Just call a method that handles onException in the constructor of the base class.
//Base class that does exception handling
public abstracExceptionRouteBuildert class BaseAbstractRoute extends RouteBuilder {
protected BaseAbstractRoute() {
handleException();
}
private void handleException() {
onException(Exception.class).handled(true).to("mock:error");
}
}
//Extend the base class
public class MyRouteBuilder extends BaseAbstractRoute {
#Override
public void configure() throws Exception {
from("direct:start").throwException(new Exception("error"));
}
}