DryIoc, Spring.Net's GetObjectsOfType equivalent? - spring.net

With Spring.Net, it's possible to query all objects of a certain (ancestor) type.
var ctx = ContextRegistry.GetContext();
var setUsers = ctx.GetObjectsOfType(typeof(ISetUser)).Values.OfType<ISetUser>().ToList();
How can this be done with DryIoc?

The direct answer given sample classes and interfaces would be:
public interface IA { }
public interface IB { }
public class AB : IA, IB { }
public class AA : IA { }
[Test]
public void Resolve_all_services_implementing_the_interface()
{
var container = new Container();
container.Register<IB, AB>();
container.Register<AA>();
// resolve IA's, even if no IA service type was registered
var aas = container.GetServiceRegistrations()
.Where(r => typeof(IA).IsAssignableFrom(r.Factory.ImplementationType ?? r.ServiceType))
.Select(r => (IA)container.Resolve(r.ServiceType))
.ToList();
Assert.AreEqual(2, aas.Count);
}
If you will want to retrieve some interface, it probably good to register it from the start (plan for it):
[Test]
public void Resolve_automatically_registered_interface_services()
{
var container = new Container();
// changed to RegisterMany to automatically register implemented interfaces as services
container.RegisterMany<AB>();
container.RegisterMany<AA>();
// simple resolve
var aas = container.Resolve<IList<IA>>();
Assert.AreEqual(2, aas.Count);
}

Related

AutoBogus configuration and Bogus Determinism

When using the AutoBogus builder configurations with either the Create or Generate methods, I can't seem to find the way I can provide the deterministic way to seed random. UseSeed is not available.
For example:
var orderFaker = AutoFaker.Create(builder => builder.WithOverride(new OrderOverride()));
orderFaker
// .UseSeed(<int>) is not available on orderFaker
.Generate(5);
Similarly,
List<Order> sut = AutoFaker.Generate<Order>(5,
builder => builder.WithOverride(new OrderOverride())
);
Am I missing something or is it just not available at this level?
As a workaround, my override class just has a static method for the Rules being applied, making applicable in the override as well as when instantiating AutoFaker<Order>. This seems to be working, but just wondering if there's a better way...
Faker<Order> orderFaker = new AutoFaker<Order>().Rules(
OrderOverride.OrderGenerator);
List<Order> actual = orderFaker
// https://github.com/bchavez/Bogus/tree/cc2f894e46be08e3a1521f31b464017666f4f8c7#determinism
// UseSeed at the faker level ensures consistent output
.UseSeed(1338)
.Generate(5)
.ToList();
public class OrderOverride : AutoGeneratorOverride
{
public override bool CanOverride(AutoGenerateContext context)
{
return context.GenerateType == typeof(Order);
}
public override void Generate(AutoGenerateOverrideContext context)
{
var o = context.Instance as Order;
var f = context.Faker;
OrderGenerator(f, o);
}
public static void OrderGenerator(Faker f, Order o)
{
o.LineItems = new AutoFaker<OrderLineItem>().GenerateBetween(2, 5);
o.Notes = f.Lorem.Text();
}
}

How to configure ninject to inject different dependency types into the same class?

I've run into what I believe must be a common dependency injection-related problem. I'm having trouble finding relevant examples, and I do not like the best solution I've been able to come up with.
public class WasherDryerFolderSystem : ILaundrySystem
{
private IWasher _washer;
private IDryer _dryer;
private IFolder _folder;
public WasherDryerFolderSystem(IWasher washer, IDryer dryer, IFolder folder)
{...}
public void DoLaundry()
{
_washer.Wash();
_dryer.Dry();
_folder.Fold();
}
}
public class HandWasher : IWasher {...}
public class MachineWasher : IWasher {...}
public class HandDryer : IDryer {...}
public class MachineDryer : IDryer {...}
public class HandFolder : IFolder {...}
public class MachineFolder : IFolder {...}
Now in the main app I have something like
var laundrySystem = _kernel.Get<ILaundrySystem>(someUserInput);
What is a good way to configure the bindings required for something like this? Here's what I've been able to come up with thus far (that I don't like):
Bind<ILaundrySystem>().To<WasherDryerFolderSystem>()
.Named(MACHINEWASH_HANDDRY_HANDFOLD)
.WithConstructorArgument("washer", new MachineWasher())
.WithConstructorArgument("dryer", new HandDryer())
.WithConstructorArgument("folder", new HandFolder());
At first I didn't think this looked too bad, but when Washers and Dryers and Folders all have their own dependencies, this quickly gets ugly.
This feels to me like it should be a common problem, but I'm not finding anything that's much help. Do I have something designed incorrectly?
You could use a factory pattern:
public interface ILaundrySystemFactory
{
ILaundrySystem Create(string someUserInput);
}
public class LaundrySystemFactory : ILaundrySystemFactory
{
private readonly IKernel _kernel;
public LaundrySystemFactory(IKernel kernel){
_kernel = kernel;
}
public ILaundrySystem Create(string someUserInput)
{
if(someUserInput){
var washer = _kernel.Get<MachineWasher>();
var dryer = _kernel.Get<HandDryer>();
var folder = _kernel.Get<HandFolder>();
} else {
var washer = _kernel.Get<DifferentWasher>();
var dryer = _kernel.Get<DifferentDryer>();
var folder = _kernel.Get<DifferentFolder>();
}
return new WasherDryerFolderSystem(washer, dryer, folder);
}
}
and then simply
private readonly ILaundrySystemFactory _laundrySystemFactory;
ctor(ILaundrySystemFactory laundrySystemFactory){
_laundrySystemFactory = laundrySystemFactory;
}
public UserInputMethod(string someUserInput)
{
var loundrySystem = laundrySystemFactory.Create(someUserInput);
var loundry = loundrySystem.DoLaundry();
}
bindings:
Bind<ILaundrySystemFactory>().To<LaundrySystemFactory>();
(some DI containers might also need something like:)
Bind<MachineWasher>().To<MachineWasher>();
Make a concrete classes with concrete parameters you need, put them as dependencies of strategy which will use them based on user input. Next instantiate them all with SINGLE call for a resolution root class. OFC Strategy can be the resolution root itself but it also can be a dependency of different resoultion root. Example:
//DoLaundry based on user input
public class WasherDryerFolderSystemStrategy
{
ctor(MachineWashingHandDringHandFoldingSystem first,
MachineWashingHandDringHandFoldingSystem second,
HandWashingHandDringHandFoldingWithBreakfastSystem third) { ... }
public void DoLaundry(int userInput)
{
if(userInput == 1)
first.DoLaundry();
if(userInput == 2)
second.DoLaundry();
if(userInput == 3)
third.DoLaundry();
}
}
// MACHINEWASH_HANDDRY_HANDFOLD
public class MachineWashingHandDringHandFoldingSystem : WasherDryerFolderSystem
{
public MachineWashingHandDringHandFoldingSystem
(MachineWasher machineWasher, HandDryer handDryer, HandFolder handFolder) :
base(machineWasher, handDryer, handFolder)
{
}
}
// HANDWASH_HANDDRY_HANDNOFOLD
public class HandWashingHandDringHandFoldingSystem : WasherDryerFolderSystem
{
public MachineWashingHandDringHandFoldingSystem
(HandWasher machineWasher, HandDryer handDryer, HandFolder handFolder) :
base(machineWasher, handDryer, handFolder)
{
}
}
// HANDWASH_HANDDRY_HANDNOFOLD_WITHBREAKFAST
public class HandWashingHandDringHandFoldingWithBreakfastSystem : WasherDryerFolderSystem
{
private readonly BreakfastMaker breakfastMaker
public MachineWashingHandDringHandFoldingSystem
(HandWasher machineWasher, HandDryer handDryer, HandFolder handFolder, BreakfastMaker brekfastMaker) :
base(machineWasher, handDryer, handFolder)
{
this.breakfastMaker = breakfastMaker
}
public overide void DoLaundry()
{
base.DoLaundry();
brekfastMaker.AndMakeChipBreakAsWell();
}
}
Please note that the implementation above does not require any Ninject configuration. Ninject will autobind everything ToSelf() with the first use (as long as it is not an interface).
In general as long as you do not need some sort of composite/bulk operations with with multiple implementations, than you should avoid interface bindings (and interfaces at all). Composite like operation example:
// original WasherDryerFolderSystem refactored
public class WasherDryerFolderSystem
{
private IEnumerable<IWasher> washers;
private IEnumerable<IDryer> dryers;
private IEnumerable<IFolder> folders;
public WasherDryerFolderSystem(
IWasher[] washers, IDryer[] dryers, IFolder[] folders)
{
this.washers = washers;
this.dryers = dryers;
this.folders = folders;
}
// all inclusive
public virtual void DoLaundry()
{
foreach (var washer in washers)
washer.Wash();
foreach (var dryer in dryers)
dryer.Dry();
foreach (var folder in folders)
folder.Fold();
}
}
I hope that helps.

Decoration using Castle DynamicProxy and StructureMap 3 in a Convention - DecorateAllWith

How to use DecorateAllWith to decorate with a DynamicProxy all instances implements an interface?
For example:
public class ApplicationServiceInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
// ...
invocation.Proceed();
// ...
}
}
public class ApplicationServiceConvention : IRegistrationConvention
{
public void Process(Type type, Registry registry)
{
if (type.CanBeCastTo<IApplicationService>() && type.IsInterface)
{
var proxyGenerator = new ProxyGenerator();
// ??? how to use proxyGenerator??
// ???
registry.For(type).DecorateAllWith(???); // How to use DecorateAllWith DynamicProxy ...??
}
}
}
I could decorate some interfaces to concrete types using (for example):
var proxyGenerator = new ProxyGenerator();
registry.For<IApplicationService>().Use<BaseAppService>().DecorateWith(service => proxyGenerator.CreateInterfaceProxyWithTargetInterface(....))
But havent able to using DecorateAll to do this.
To call registry.For<>().Use<>().DecorateWith() I have to do this:
if (type.CanBeCastTo<IApplicationService>() && !type.IsAbstract)
{
var interfaceToProxy = type.GetInterface("I" + type.Name);
if (interfaceToProxy == null)
return null;
var proxyGenerator = new ProxyGenerator();
// Build expression to use registration by reflection
var expression = BuildExpressionTreeToCreateProxy(proxyGenerator, type, interfaceType, new MyInterceptor());
// Register using reflection
var f = CallGenericMethod(registry, "For", interfaceToProxy);
var u = CallGenericMethod(f, "Use", type);
CallMethod(u, "DecorateWith", expression);
}
Only for crazy minds ...
I start to get very tired of StructureMap, many changes and no documentation, I have been read the source code but ... too many efforts for my objective ...
If someone can give me a bit of light I will be grateful.
Thanks in advance.
In addition ... I post here the real code of my helper to generate the expression tree an register the plugin family:
public static class RegistrationHelper
{
public static void RegisterWithInterceptors(this Registry registry, Type interfaceToProxy, Type concreteType,
IInterceptor[] interceptors, ILifecycle lifecycle = null)
{
var proxyGenerator = new ProxyGenerator();
// Generate expression tree to call DecoreWith of StructureMap SmartInstance type
// registry.For<interfaceToProxy>().Use<concreteType>()
// .DecoreWith(ex => (IApplicationService)
// proxyGenerator.CreateInterfaceProxyWithTargetInterface(interfaceToProxy, ex, interceptors)
var expressionParameter = Expression.Parameter(interfaceToProxy, "ex");
var proxyGeneratorConstant = Expression.Constant(proxyGenerator);
var interfaceConstant = Expression.Constant(interfaceToProxy);
var interceptorConstant = Expression.Constant(interceptors);
var methodCallExpression = Expression.Call(proxyGeneratorConstant,
typeof (ProxyGenerator).GetMethods().First(
met => met.Name == "CreateInterfaceProxyWithTargetInterface"
&& !met.IsGenericMethod && met.GetParameters().Count() == 3),
interfaceConstant,
expressionParameter,
interceptorConstant);
var convert = Expression.Convert(methodCallExpression, interfaceToProxy);
var func = typeof(Func<,>).MakeGenericType(interfaceToProxy, interfaceToProxy);
var expr = Expression.Lambda(func, convert, expressionParameter);
// Register using reflection
registry.CallGenericMethod("For", interfaceToProxy, new[] {(object) lifecycle /*Lifecicle*/})
.CallGenericMethod("Use", concreteType)
.CallNoGenericMethod("DecorateWith", expr);
}
}
public static class CallMethodExtensions
{
/// <summary>
/// Call a method with Generic parameter by reflection (obj.methodName[genericType](parameters)
/// </summary>
/// <returns></returns>
public static object CallGenericMethod(this object obj, string methodName, Type genericType, params object[] parameters)
{
var metod = obj.GetType().GetMethods().First(m => m.Name == methodName && m.IsGenericMethod);
var genericMethod = metod.MakeGenericMethod(genericType);
return genericMethod.Invoke(obj, parameters);
}
/// <summary>
/// Call a method without Generic parameter by reflection (obj.methodName(parameters)
/// </summary>
/// <returns></returns>
public static object CallNoGenericMethod(this object obj, string methodName, params object[] parameters)
{
var method = obj.GetType().GetMethods().First(m => m.Name == methodName && !m.IsGenericMethod);
return method.Invoke(obj, parameters);
}
}
Almost two years later I have needed return this issue for a new project. This time I have solved it this time I have used StructureMap 4.
You can use a custom interceptor policy to decorate an instance in function of his type. You have to implement one interceptor, one interceptor policy and configure it on a registry.
The Interceptor
public class MyExInterceptor : Castle.DynamicProxy.IInterceptor
{
public void Intercept(Castle.DynamicProxy.IInvocation invocation)
{
Console.WriteLine("-- Call to " + invocation.Method);
invocation.Proceed();
}
}
The interceptor policy
public class CustomInterception : IInterceptorPolicy
{
public string Description
{
get { return "good interception policy"; }
}
public IEnumerable<IInterceptor> DetermineInterceptors(Type pluginType, Instance instance)
{
if (pluginType == typeof(IAppService))
{
// DecoratorInterceptor is the simple case of wrapping one type with another
// concrete type that takes the first as a dependency
yield return new FuncInterceptor<IAppService>(i =>
(IAppService)
DynamicProxyHelper.CreateInterfaceProxyWithTargetInterface(typeof(IAppService), i));
}
}
}
Configuration
var container = new Container(_ =>
{
_.Policies.Interceptors(new CustomInterception());
_.For<IAppService>().Use<AppServiceImplementation>();
});
var service = container.GetInstance<IAppService>();
service.DoWork();
You can get a working example on this gist https://gist.github.com/tolemac/3e31b44b7fc7d0b49c6547018f332d68, in the gist you can find three types of decoration, the third is like this answer.
Using it you can configure the decorators of your services easily.

Converting Caching Pattern from Structuremap to AutoFac

I'm switching over from structure map to Autofac. I've use a caching pattern from Scott Millett's book ASP.net Design Patterns which implements an interface for both Cache and the Repository and switches in the appropriate object depending on the constructor parameter name
The interface looks like this
public interface ISchemeRepository
{
List<Scheme> GetSchemes();
}
The cache object looks like this
public class SchemeRepository : BaseRepository, ISchemeRepository
{
/***************************************************************
* Properties
***************************************************************/
private readonly ISchemeRepository schemeRepository;
/***************************************************************
* Constructors
***************************************************************/
public SchemeRepository()
: this(ObjectFactory.GetInstance<ISchemeRepository>(), ObjectFactory.GetInstance<IConfigurationSetting>())
{
}
public SchemeRepository(ISchemeRepository realSchemeRepository, IConfigurationSetting configurationSetting)
{
schemeRepository = realSchemeRepository;
this.configurationSetting = configurationSetting;
}
/**************************************************************
* Methods
***************************************************************/
public List<Scheme> GetSchemes()
{
string key = Prefix + "Schemes";
if (!MemoryCache.Default.Contains(key))
{
MemoryCache.Default.Add(key, schemeRepository.GetSchemes(), new CacheItemPolicy());
}
return (List<Scheme>)MemoryCache.Default.Get(key);
}
}
The repository looks like this
public class SchemeRepository : BaseLocalRepository, ISchemeRepository
{
/***************************************************************
* Properties
***************************************************************/
private readonly IConnectionSetting connectionSetting;
/***************************************************************
* Constructors
***************************************************************/
public SchemeRepository()
: this(ObjectFactory.GetInstance<IConnectionSetting>())
{
}
public SchemeRepository(IConnectionSetting connectionSetting)
{
this.connectionSetting = connectionSetting;
}
/**************************************************************
* Methods
***************************************************************/
public List<Scheme> GetSchemes()
{
var response = new List<Scheme>();
var conn = new SqlConnection(connectionSetting.CQBConnectionString);
var command = new SqlCommand("proc_GetSchemes", conn) { CommandType = CommandType.StoredProcedure };
conn.Open();
var reader = command.ExecuteReader();
while (reader.Read())
{
response.Add(
new Scheme
{
SchemeId = reader["Scheme_Id"].ToString().Trim(),
GuaranteeText = reader["Guarantee_Text"].ToString().Trim()
}
);
}
conn.Close();
return response;
}
}
The structure map call is below
InstanceOf<Repository.Local.Contract.IProviderRepository>().Is.OfConcreteType<Repository.Local.Core.ProviderRepository>().WithName("RealProviderRepository");
ForRequestedType<Repository.Local.Contract.IProviderRepository>().TheDefault.Is.OfConcreteType<Repository.Local.Cache.ProviderRepository>().CtorDependency<Repository.Local.Contract.IProviderRepository>().Is(x => x.TheInstanceNamed("RealProviderRepository"));
Structure map looks at the constructor and if it contains a parameter called "realSchemeRepository" then it implements the object that connect to the database, if not it implements the cache object that checks the cache and calls the database if nothing is in the cache and populates the cache.
How do I do this in Autofac? Is there a better way of doing this in Autofac?
I believe what you're asking how to do is set up a decorator between your two repository classes. I'm gonna pretend the two class names are CacheSchemeRepository and RealSchemeRepository because naming them exactly the same is confusing and terrible. Anyways...
builder.Register(c => new RealSchemeRepository(c.Resolve<IConnectionSetting>())
.Named<ISchemeRepository>("real");
builder.RegisterDecorator<ISchemeRepository>(
(c, inner) => new CacheSchemeRepository(inner, c.Resolve<IConfigurationSetting>()),
"real");

Windsor Resolving generic service SubTypes

interface IFoo<T> { }
interface IBar { }
class BarImpl : IBar { }
class FooImplA : IFoo<IBar> { }
class FooImplB : IFoo<BarImpl> { }
container.Register(
AllTypes.Of(typeof(IFoo<>)).From(assem)
.WithService.FirstInterface());
var bars = container.ResolveAll<IFoo<BarImpl>>();
Is there anyway to setup the Windsor container resolution so that bars will include both FooImplA and FooImplB?
You can't. Why? Try to run this, which is what you want Windsor to do.
var a = new FooImplA();
var b = new FooImplB();
var bars = new IFoo<BarImpl>[] { a, b };
It won't compile.
Well, this is how I "solved" this... although I'm still thinking that it's possible either I didn't understand my own problem, or am attempting something that is silly.
private static IEnumerable<object> ResolveTypeHierarchy(Type type, Type msgType) {
var handlers = new List<object>();
foreach (var interfaceType in msgType.GetInterfaces()) {
var gType = type.MakeGenericType(interfaceType);
handlers.AddRange(container.ResolveAll(gType));
}
var baseType = msgType;
while (null != baseType) {
var gType = type.MakeGenericType(baseType);
handlers.AddRange(container.ResolveAll(gType));
baseType = baseType.BaseType;
}
return handlers;
}
ResolveTypeHierarchy(typeof(IFoo<>), typeof(BarImpl));
=> { FooImplA, FooImplB }
I should probably note that this was taken from researching and peering through the Rhino.ServiceBus code.

Resources