How do I register a generic class to be resolved when the generic argument is based on a certain type? - inversion-of-control

How do I register IPetFactory<TPet> to be resolved with DefaultPetFactory<TPet> where TPet can be any class based on Pet in the example below?
I'd like to be able to resolve IPetFactory<Dog> with DefaultPetFactory<Dog>.
I've just found examples using BasedOn where the Factory itself is based on a class, not the generic argument.
class Pet
{
public string Name { get; set; }
}
class Fish : Pet {}
class Dog : Pet {}
class Cat : Pet { }
interface IPetFactory<TPet> where TPet : Pet;
class DefaultPetFactory<TPet> : IPetFactory<Pet> where TPet : Pet
{
// default implementation
}
My real implementation has a lot of classes based on Pet so I'm looking for a more generic approach than just calling register on each of them.
EDIT:
I found out the problem wasn't what I thought it was. It was due to the generic arguments and an exception of “the arity of the generic type definition” which caused my problems.
And I over-simplified my example. In my real implementation I have to generic arguments and it turns out Windsor need the the same generic parameters to be able to resolve the type.
If I do like this it won't work.
class Owner
{
}
class DefaultPetFactory<TPet> : IPetFactory<Owner, TPet> where TPet : Pet
{
// default implementation
}
If I do like this it will:
class DefaultPetFactory<TOwner, TPet> : IPetFactory<TOwner, TPet>
where TOwner : Owner
where TPet : Pet
{
// default implementation
}
If anyone has a better solution to this, preferably with the registrations it's appreciated. I don't like to change my classes to make the registration work.

(For the updated question)
There is a ticket in Windsor's issue tracker to support scenarios like that (feel free to vote for it), but in general this is something very hard to implement... generically (no pun intended), and as far as I know no container currently supports it.
In Windsor 3 you can workaround it by implementing a new interface called IGenericImplementationMatchingStrategy doing roughly the following (untested, I'm writing this from memory):
public class PetMatcher: IGenericImplementationMatchingStrategy
{
public Type[] GetGenericArguments(ComponentModel model, CreationContext context)
{
if (SomePreconditionToMakeSureThatsReallyTheScenarioDescribedAbove() == false )
{
return null;// which will fallback to default behaviour
}
// implementation needs just one generic arg, second of two the interface has
return new[]{ context.GenericArguments[1] };
}
}
You then register this as follows:
Container.Register(
Classes.FromAssemblyContaining(typeof(IPetFactory<,>)).BasedOn(typeof(IPetFactory<,>))
.WithServiceBase()
.Configure(
c => c.ExtendedProperties(
Property.ForKey(ComponentModel.GenericImplementationMatchingStrategy)
.Eq(new PetMatcher()))));

Related

How to define a class that is exactly the same as another class in Dart/Flutter

I'm defining some custom Exceptions in Dart.
I want in my logic to check the type of exception and base my processing on that, so I want to create distinct classes for each, for example like this :
class FailedToLoadCriticalDataException implements Exception { } // app cannot continue
class FailedToLoadNonCriticalDataException implements Exception { } // app can continue
However I also want to pass 2 parameters when I create these types of exceptions, the type of API call, and the API url, and the definition for that would look like this :
class UrlCallFailedException implements Exception {
String _dataTypeName;
String _urlEndpoint;
UrlCallFailedException([this._dataTypeName, this._urlEndpoint]);
#override
String toString() {
return "(${this.runtimeType.toString()}) Failed to fetch $_dataTypeName ($_urlEndpoint)";
}
}
Now what I want to do is (replace the initial definitions I made earlier and re)define my FailedToLoadCriticalDataException and FailedToLoadNonCriticalDataException classes so that they are exactly the code that is in the UrlCallFailedException class.
Is there any way to simply say something like class FailedToLoadCriticalDataException **is** UrlCallFailedException; and not need to duplicate the code that defines UrlCallFailedException ?
class FailedToLoadCriticalDataException implements UrlCallFailedException{ } is wrong because it is "Missing concrete implementations of 'getter UrlCallFailedException._dataTypeName',.."
class FailedToLoadCriticalDataException extends UrlCallFailedException{ } is wrong because when I got to throw FailedToLoadNonCriticalDataException("Foo", url); it's expectation is that there are no params ("Too many positional arguments: 0 expected, but 2 found.").
Is there a way to create multiple classes that behave exactly the same as another type and differ only in their class, without duplicating all the code ?
I've come up with this as a decent compromise :
class FailedToLoadCriticalDataException extends UrlCallFailedException {
FailedToLoadCriticalDataException([dataTypeName, urlEndpoint]) {
super._dataTypeName = dataTypeName;
super._urlEndpoint = urlEndpoint;
}
}
class FailedToLoadNonCriticalDataException extends UrlCallFailedException {
FailedToLoadNonCriticalDataException([dataTypeName, urlEndpoint]) {
super._dataTypeName = dataTypeName;
super._urlEndpoint = urlEndpoint;
}
}
Some, but minimal, code duplication, and I can now call throw FailedToLoadNonCriticalDataException("Foo", url); in my code later.

How can an abstract implement an interface?

I have a common interface that describes access to the output stream like this:
interface IOutput {
function writeInteger(aValue:Int):Void;
}
And I have an abstract implementation of this interface based on standard haxe.io.BytesOutput class:
abstract COutput(BytesOutput) from BytesOutput {
public inline function new(aData:BytesOutput) {
this = aData;
}
public inline function writeInteger(aValue:Int):Void {
this.writeInt32(aValue);
}
}
Though this abstract is truly implementing interface described above there's no direct reference to interface and when I'm trying to use it like this:
class Main {
public static function out(aOutput:IOutput) {
aOutput.writeInteger(0);
}
public static function main() {
var output:COutput = new BytesOutput();
out(output); // type error
}
}
Compiler throws an error: COutput should be IOutput. I can solve this problem only through using common class that wraps BytesOutput and implements IOutput.
My question is how to show the Haxe compiler that the abstract implements the interface.
Abstracts can't implement interfaces because they're a compile-time feature and don't exist at runtime. This conflicts with interfaces, they do exist at runtime and dynamic runtime checks like Std.is(something, IOutput) have to work.
Haxe also has a mechanism called structural subtyping that can be used as an alternative to interfaces. With this approach, there's no need for an explicit implements declaration, it's good enough if something unifies with a structure:
typedef IOutput = {
function writeInteger(aValue:Int):Void;
}
Unfortunately, abstracts aren't compatible with structural subtyping either due to the way they're implemented.
Have you considered using static extensions instead? At least for your simple example, that seems like the perfect solution for making a writeInteger() method available for any haxe.io.Output:
import haxe.io.Output;
import haxe.io.BytesOutput;
using Main.OutputExtensions;
class Main {
static function main() {
var output = new BytesOutput();
output.writeInteger(0);
}
}
class OutputExtensions {
public static function writeInteger(output:Output, value:Int):Void {
output.writeInt32(value);
}
}
You could even combine this with structural subtyping so writeInteger() becomes available on anything that has a writeInt32() method (try.haxe link):
typedef Int32Writable = {
function writeInt32(value:Int):Void;
}
As #Gama11 states, abstracts cannot implement interfaces. In Haxe, for type to implement an interface, it must be able to be compiled to something class-like that can be called using the interface’s methods without any magic happening. That is, to use a type as its interface, there needs to be a “real” class implementing that type. Abstracts in Haxe compile down to their base type—the abstract itself is entirely invisible after compilation happens. Thus, at runtime, there is no instance of a class with the methods defined in your abstract which implement the interface.
However, you can make your abstract appear to implement an interface by defining an implicit conversion to the interface you are trying to implement. For your example, the following might work:
interface IOutput {
function writeInteger(aValue:Int):Void;
}
abstract COutput(BytesOutput) from BytesOutput {
public inline function new(aData:BytesOutput) {
this = aData;
}
#:to()
public inline function toIOutput():IOutput {
return new COutputWrapper((cast this : COutput));
}
public inline function writeInteger(aValue:Int):Void {
this.writeInt32(aValue);
}
}
class COutputWrapper implements IOutput {
var cOutput(default, null):COutput;
public function new(cOutput) {
this.cOutput = cOutput;
}
public function writeInteger(aValue:Int) {
cOutput.writeInteger(aValue);
}
}
class Main {
public static function out(aOutput:IOutput) {
aOutput.writeInteger(0);
}
public static function main() {
var output:COutput = new BytesOutput();
out(output);
out(output);
}
}
Run on try.haxe.org
Note that, each time an implicit conversion happens, a new instance of the wrapper will be constructed. This may have performance implications. If you only access your value through its interface, consider setting the type of your variable to the interface rather than the abstract.
This is similar to “boxing” a primitive/value type in C#. In C#, value types, defined using the struct keyword, are allowed to implement interfaces. Like an abstract in Haxe, a value type in C# is compiled (by the JITter) into untyped code which simply directly accesses and manipulates the value for certain operations. However, C# allows structs to implement interfaces. The C# compiler will translate any attempt to implicitly cast a struct to an implemented interface into the construction of a wrapper class which stores a copy of the value and implements the interface—similar to our manually authored wrapper class (this wrapper class is actually generated by the runtime as part of JITing and is performed by the IL box instruction. See M() in this example). It is conceivable that Haxe could add a feature to automatically generate such a wrapper class for you like C# does for struct types, but that is not currently a feature. You may, however, do it yourself, as exemplified above.

PostSharp C# - How to Implement All Fields Required

PostSharp contracts make it easy to label individual fields as Required. But I want a class attribute that makes all of the class fields required. I'm guessing I would have to implement a custom aspect to support this.
It seems like it would be a common need for anyone passing around data containers. Can anyone direct me to some code that implements a custom "AllFieldsRequired" aspect in PostSharp?
You can implement PostSharp.Aspects.IAspectProvider:
public class AllFieldsRequiredAttribute : TypeLevelAspect, IAspectProvider
{
IEnumerable<AspectInstance> IAspectProvider.ProvideAspects(object targetElement)
{
Type type = (Type)targetElement;
return type.GetFields().Select(
m => new AspectInstance(m, new ObjectConstruction(typeof(RequiredAttribute))));
}
}
[AllFieldsRequired]
public class Foo
{
public string Bar;
public object Baz;
}

Using Unity, how do you register type mappings for generics?

I'm trying to implement a repository solution for Entity Framework but I am having trouble registering the types that include generics using Unity.
Given:
// IRepository interface
public interface IRepository<TEntity>
{
// omitted for brevity
}
// Repository implementation
public class Repository<TEntity, TContext> : IRepository<TEntity>, IDisposable
where TEntity : class
where TContext : DbContext
{
// omitted for brevity
}
// service layer constructor
public MyServiceConstructor(IRepository<Account> repository)
{
_repository = repository;
}
I need to register the type mapping for IRepository to Repository. but I'm having trouble with the Unity syntax for this kind of mapping.
I have tried the following with no luck:
container.RegisterType<IRepository<>, typeof(Repository<,>)>();
container.RegisterType<typeof(IRepository<>), Repository<,>>();
EDIT
Based, on #Steven response I have the following implementation now:
// UnityRepository implementation
public class UnityRepository<TEntity> : Repository<TEntity, MyDbContextEntities>
where TEntity : class
{
public UnityRepository() : base(new MyDbContextEntities()) { }
}
// Unity bootstrapper
container.RegisterType(typeof(IRepository<>), typeof(UnityRepository<>));
You are trying to do the following:
container.RegisterType(typeof(IRepository<>), typeof(Repository<,>));
This would normally work, but won't do the trick in this case, since there is IRepository<TEntity> has one generic argument and Repository<TEntity, TContext> has two, and Unity (obviously) can't guess what type it should fill in for TContext.
What you need is this:
container.RegisterType(
typeof(IRepository<>),
typeof(Repository<, MyDbContextEntities>));
In other words, you'd want to supply the Repository<TEntity, TContext> as a partial open generic type (with one parameter filled in). Unfortunately, the C# compiler does not support this.
But even if the C# did support this, Unity doesn't support partial open generic types. In fact most IoC libraries eworks don't support this. And for that one library that does support it, you would still have to do the following (nasty thing) to create the partial open generic type:
Type myDbContextEntitiesRepositoryType =
typeof(Repository<,>).MakeGenericType(
typeof(Repository<,>).GetGenericParameters().First(),
typeof(MyDbContextEntities));
There's a easy trick work around to get this to work though: define a derived class with one generic type:
// Special implementation inside your Composition Root
public class UnityRepository<TEntity> : Repository<TEntity, MyDbContextEntities>
where TEntity : class
{
public UnityRepository([dependencies]) : base([dependencies]) { }
}
Now we can easily register this open generic type:
container.RegisterType(typeof(IRepository<>), typeof(UnityRepository<>));

How can I achieve this in Windsor Castle? (Migrating from StructureMap)

I need to modify an existing web app to use Castle.Windsor as IOC container. It was originally developed with StructureMap.
I am stuck with the following problem.
Lets say I have registered a couple of interfaces and their corresponding implementations:
IFoo -> Foo
IBar -> Bar
Calling container.Resolve<IFoo>() or container.Resolve<IBar>() works just fine. This means that the services are registered correctly.
I have a Web Api class with dependencies on other services, such as IFoo
public class BadRequestErrorHandler : HttpErrorHandler
{
// services
public BadRequestErrorHandler(IFoo foo) {...} // has dependency on IFoo
}
In StructureMap I can call:
var test = ObjectFactory.GetInstance<BadRequestErrorHandler>();
this will resolve the IFoo dependency.
Now this does not work with windsor.
How can this be achieved with windsor?
Thanks!
* EDIT *
I was just able to make it work by explicitely registering the BadRequestErrorHandler.
container.Register(Component.For<BadRequestErrorHandler>());
I am just hoping there is a better way to achieve this, that does not involve registering classes that have dependencies. I have a bunch of them...
* EDIT 2 **
To ease the pain, I added a special method to deal with these concrete types.
public T GetInstanceWithAutoRegister<T>()
{
if (container.Kernel.GetHandler(typeof(T)) == null)
{
container.Register(Component.For<T>());
}
return container.Resolve<T>();
}
public object GetInstanceWithAutoRegister(Type pluginType)
{
if (container.Kernel.GetHandler(pluginType) == null)
{
container.Register(Component.For(pluginType));
}
return container.Resolve(pluginType);
}
not ideal, but at least better than having to explicetly register each type. Hope someone has a better solution
You can achieve what you want by registering an ILazyComponentLoader which is a hook that gets called by Windsor as a "last resort" when a component cannot be resolved.
In your case, the implementation would probably look somewhat like this:
public class JustLetWindsorResolveAllConcreteTypes : ILazyComponentLoader
{
public IRegistration Load(string key, Type service)
{
return Component.For(service);
}
}
-and then it should be registered as such:
container.Register(Component.For<ILazyComponentLoader>()
.ImplementedBy<JustLetWindsorResolveAllConcreteTypes>());
You can read more about it in the docs.