I am trying to do something like this. However the WithMetadata method wont let me.
Is this a problem in Autofac and should TScanningActivatorData in the WithMetadata overloads be changed to TActivatorData, or am i approaching this the wrong way?
builder.RegisterType(myType).As<IMyType().AsSelf().WithMetadata("somekey", delegate(Type t)
{
//dosomething
return t;
});
This gives me the error on the WithMetadata method: The type 'Autofac.Builder.ConcreteReflectionActivatorData' cannot be used as type parameter 'TScanningActivatorData' in the generic type or method 'Autofac.RegistrationExtensions.WithMetadata<TLimit,TScanningActivatorData,TRegistrationStyle>(Autofac.Builder.IRegistrationBuilder<TLimit,TScanningActivatorData,TRegistrationStyle>, string, System.Func<System.Type,object>)'. There is no implicit reference conversion from 'Autofac.Builder.ConcreteReflectionActivatorData' to 'Autofac.Features.Scanning.ScanningActivatorData'.
There's a more suitable overload for what you're trying to achieve. The t parameter passed in to the delegate is the same as myType - so the equivalent code is:
var someValue = DoSomething(myType);
builder.RegisterType(myType)
.As<IMyType>()
.AsSelf()
.WithMetadata("somekey", someValue);
The overload you've been looking at is for use with scanning registrations, e.g. when using RegisterAssemblyTypes() rather than RegisterType().
Hope this helps.
Nick
Related
I would like to know if there is a way to do a cast from Single<Object> to Single<CustomClass>.
I have a class that implements a method that should return a Single<Customer>, I implemented the search like here
Single.create(single -> {
CustomerServiceDto customer = mapper.map(customerRepository.findById(id).get(), CustomerServiceDto.class);
single.onSuccess(customer);
});
There isn't any problem. It's what I need. This create returns me a Single<Customer> but when I implement another function to handling an exception
Single.create(single -> {
CustomerServiceDto customer = mapper.map(customerRepository.findById(id).get(), CustomerServiceDto.class);
single.onSuccess(customer);
}).onErrorReturn(error -> new CustomerServiceDto());
It returns me a Single<Object>. Can I do a casting here? To avoid change the method's signature. I tried with the classic (Single<Customer>) Single<Object> instance, but it isn't work. Thanks for your advice.
The answer was the #dano's comment. Thanks, #dano.
I'm having some issues with a Wicket (8.0.0-M4) NumberTextField in Kotlin (1.1.0).
My stripped-down form looks like this:
class Test : AbstractWebPage() {
val housenumberModel: Model<Int> = Model<Int>()
val housenumber = NumberTextField<Int>("housenumberModel", housenumberModel)
val form: Form<Unit> = object : Form<Unit>("adressForm") {}
override fun onInitialize() {
super.onInitialize()
form.add(housenumber.setRequired(false))
form.add(object : SubmitLink("submit") {
override fun onSubmit() {
super.onSubmit()
println(housenumberModel.`object`) // this is line 28
}
})
add(form)
}
}
After submitting the form I get the following stacktrace:
java.lang.ClassCastException: java.lang.String cannot be cast to
java.lang.Number
at com.mycompany.test.pages.Test$onInitialize$1.onSubmit(Test.kt:28)
at org.apache.wicket.markup.html.form.Form.delegateSubmit(Form.java:1312)
at org.apache.wicket.markup.html.form.Form.process(Form.java:979)
at org.apache.wicket.markup.html.form.Form.onFormSubmitted(Form.java:802)
at org.apache.wicket.markup.html.form.Form.onRequest(Form.java:715)
at org.apache.wicket.core.request.handler.ListenerRequestHandler.internalInvoke(ListenerRequestHandler.java:301)
at org.apache.wicket.core.request.handler.ListenerRequestHandler.invoke(ListenerRequestHandler.java:250)
at org.apache.wicket.core.request.handler.ListenerRequestHandler.invokeListener(ListenerRequestHandler.java:210)
at org.apache.wicket.core.request.handler.ListenerRequestHandler.respond(ListenerRequestHandler.java:203)
at org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor.respond(RequestCycle.java:912)
at org.apache.wicket.request.RequestHandlerExecutor.execute(RequestHandlerExecutor.java:65)
at org.apache.wicket.request.cycle.RequestCycle.execute(RequestCycle.java:283)
at org.apache.wicket.request.cycle.RequestCycle.processRequest(RequestCycle.java:253)
at org.apache.wicket.request.cycle.RequestCycle.processRequestAndDetach(RequestCycle.java:221)
at org.apache.wicket.protocol.http.WicketFilter.processRequestCycle(WicketFilter.java:262)
at org.apache.wicket.protocol.http.WicketFilter.processRequest(WicketFilter.java:204)
at org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.java:286)
[...]
If I use
val housenumberModel: Model<Int> = Model.of(0)
instead of
val housenumberModel: Model<Int> = Model<Int>()
everything works fine. But since my NumberTextField is optional I don't want to have it pre-initialized with 0.
Me and my colleagues were trying to change the type signature of the Model in every way we could imagine but came to no solution. A co-worker suggested to write a custom Wicket converter since Kotlins Int is represendeted as a primitive type (From the docs: "On the JVM, non-nullable values of this type are represented as values of the primitive type int.") Even though I don't know yet if this would work it seems like an overkill for me.
Another hack I could think of: writing some JavaScript to delete the zero from the input field. Also not really something I would want to do.
Question: Is there a simple solution to my problem?
(And as a bonus-question: has already anyone written a larger Wicket application in Kotlin and could tell me if this combination is ready for prime time to develop a critical project with this stack or is my problem just the tip of the iceberg?)
[edit]
Solution as pointed out by svenmeier:
Using
val housenumber = NumberTextField<Int>("housenumberModel", housenumberModel, Int::class.java)
works.
Or as an alternative:
val housenumbervalue: Int? = null
val housenumberModel: IModel<Int> = PropertyModel<Int>(this, "housenumbervalue")
val housenumber = NumberTextField<Int>("housenumberModel", housenumberModel)
Because of type erasure your NumberTextField cannot detect the generic type parameter of your model. Since your model object is null, it cannot be used to derive the type either.
In this case Wicket assumes a String model object type :/.
Either provide the type to the NumberTextField explicitly, or use a model that keeps its generic information, e.g. a PropertyModel.
There is a way to tell wicket about the type you want, it is by adding the type in the constructor. More here.
In Java it looks like this:
new NumberTextField<Integer>("housenumberModel", housenumberModel, Integer.class);
I created an extension method that lets me treat a List as DbSet for testing purposes (actually, I found this idea in another question here on stack overflow, and it's been fairly useful). Coded as follows:
public static DbSet<T> AsDbSet<T>(this List<T> sourceList) where T : class
{
var queryable = sourceList.AsQueryable();
var mockDbSet = new Mock<DbSet<T>>();
mockDbSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(queryable.Provider);
mockDbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(queryable.Expression);
mockDbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
mockDbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(queryable.GetEnumerator());
mockDbSet.Setup(d => d.Add(It.IsAny<T>())).Callback<T>(sourceList.Add);
mockDbSet.Setup(d => d.Find(It.IsAny<object[]>())).Callback(sourceList.Find);
return mockDbSet.Object;
}
I had been using Add for awhile, and that works perfectly. However, when I try to add the callback for Find, I get a compiler error saying that it can't convert a method group to an action. Why is sourceList.Add an Action, but sourceList.Find is a method group?
I'll admit I'm not particularly familiar with C# delegates, so it's likely I'm missing something very obvious. Thanks in advance.
The reason Add works is because the List<T>.Add method group contains a single method which takes a single argument of type T and returns void. This method has the same signature as an Action<T> which is one of the overloads of the Callback method (the one with a single generic type parameter, Callback<T>), therefore the List<T>.Add method group can be converted to an Action<T>.
With Find, you are trying to call the Callback method (as opposed to Callback<T>) which expects an Action parameter (as opposed to Action<T>). The difference here is that an Action does not take any parameters, but an Action<T> takes a single parameter of type T. The List<T>.Find method group cannot be converted to an Action because all the Find methods (there is only one anyway) take input parameters.
The following will compile:
public static DbSet<T> AsDbSet<T>(this List<T> sourceList) where T : class
{
var mockDbSet = new Mock<DbSet<T>>();
mockDbSet.Setup(d => d.Find(It.IsAny<object[]>())).Callback<Predicate<T>>(t => sourceList.Find(t));
return mockDbSet.Object;
}
Note that I have called .Callback<Predicate<T>> because the List<T>.Find method expects and argument of type Predicate. Also note I have had to write t => sourceList.Find(t) instead of sourceList.Find because Find returns a value (which means it doesn't match the signature of Action<Predicate<T>>). By writing it as a lambda expression the return value will be thrown away.
Note that although this compiles it will not actually work because the DbSet.Find method actually takes an object[] for it's parameter, not a Predicate<T>, so you will likely have to do something like this:
public static DbSet<T> AsDbSet<T>(this List<T> sourceList) where T : class
{
var mockDbSet = new Mock<DbSet<T>>();
mockDbSet.Setup(d => d.Find(It.IsAny<object[]>())).Callback<object[]>(keyValues => sourceList.Find(keyValues.Contains));
return mockDbSet.Object;
}
This last point has more to do with how to use the Moq library that how to use method groups, delegates and lambdas - there is all sorts of syntactic sugar going on with this line which is hiding what is actually relevant to the compiler and what isn't.
I'm trying to subclass the native JS Error object in CoffeeScript to get specialized error types, but i found that the instanceof does not work correctly if i don't define a constructor in the subclasses:
class SimpleError extends Error
class EmptyConstructorError extends Error
constructor: ->
class SuperConstructorError extends Error
constructor: ->
super
new SimpleError instanceof SimpleError # -> false
new EmptyConstructorError instanceof EmptyConstructorError # -> true
new SuperConstructorError instanceof SuperConstructorError # -> true
The problem seems to be caused by how the generated JS constructor functions are defined. When i don't define a constructor in CoffeeScript:
SimpleError = (function(_super) {
__extends(SimpleError, _super);
function SimpleError() {
return SimpleError.__super__.constructor.apply(this, arguments);
}
return SimpleError;
})(Error);
And when i do define a constructor in CoffeeScript:
SuperConstructorError = (function(_super) {
__extends(SuperConstructorError, _super);
function SuperConstructorError() {
SuperConstructorError.__super__.constructor.apply(this, arguments);
}
return SuperConstructorError;
})(Error);
As you can see, the difference is a simple return in the first case. I don't understand why this makes any difference in the instanceof behavior though, as the super constructor is just being applied to the this object (i.e. the super constructor is not being called with new), but then again i don't understand a whole lot of how JS constructors work =P
And the weird thing is that this behavior seems to only happen when subclassing native JS objects. If i subclass CoffeeScript classes everything works as expected.
Any idea of why this might be happening and how could i avoid writing dummy constructors just for the instanceof operator to work correctly?
Thanks!
Update
So the user matyr answered with a link to the commit where this behavior was introduced, but it doesn't quite explain what is happening here, so i'll try to explain that a little bit in case anyone else wonders why this works this way.
The main problem is this inherited nasty "feature" from JavaScript which let us define a constructor function that returns an object other than the one being constructed:
function Foo() {
return {'LOL': 'You fool!'};
}
new Foo() instanceof Foo // -> false
And there is also the fact that some native constructors, like Error, Array, String and whatnot don't need to be called with new: they will just return a new object of the corresponding type if you happen to forget it.
In the end, add these two ugly things together and the result is that you should remember to write class MyError extends Error then constructor: -> super instead of the more intuitive class MyError extends Error if you want the instanceof operator to work properly with MyError. That's because CoffeeScript's implicit constructor will just return whatever the parent constructor returns, and in this case will do return Error.apply(this, arguments) which will just return a shinny new error object instead of the object you passed as the this argument. Yay!
Update 2 (Feb 25 2013)
This problem was fixed in CoffeeScript 1.5.0! =D
Now extending native objects works as expected:
class MyError extends Error
new MyError instanceof MyError # -> true :)
Update 3 (Mar 04 2013)
Aaand it's gone on 1.6.0 =P
For better or worse, the return was added on 1.3.1 to fix #1966 (and #2111).
I have my own SmartPointer class.
There are cases where SmartPtr contain a class that inherite from a Base class, and I would like to convert SmartPtr<ClassX> into SmartPtr<BaseClassOfClassX>;
I am trying to overload the SmartPtr Conversion operator to do this.
It work fine for the Class themself, such as:
template<class newType>
operator SmartPtr<newType>() const
{
return SmartPtr<newType>((SmartPtr<newType>*)this);
}
but not for pointer to the Class, I have tried the following, and it never gets call and get the following error:
template<class newType>
operator SmartPtr<newType>*() const
{
return static_cast<SmartPtr<newType>*>(this);
}
Simple code to get the error:
SmartPtr<ClassX> test(pClassX);
SmartPtr<BaseClassOfClassX>* ob = &test;
ERROR:
cannot convert from 'SmartPtr<T> *' to 'SmartPtr<T> *'
Does anyone see what is wrong with my second conversion overload?
Thanks
From the C++ standard: "An operator function shall either be a non-static member function or be a non-member function and have at least one
parameter whose type is a class, a reference to a class, an enumeration, or a reference to an enumeration."
As the type of &test is not a class nor anything implicitly convertible to a class, you cannot overload the typecasts on the pointer directly. Depending on why you need pointers to your smart pointers, maybe you really want to employ references which is much more common.