Smart.Resolver .NET is simplified resolver library, degradation version of Ninject.
public interface IService
{
}
public class Service : IService
{
}
public class Controller
{
private IService Service { get; }
public Controller(IService service)
{
Service = service;
}
}
// Usage
var config = new ResolverConfig();
config.Bind<IService>().To<Service>().InSingletonScope();
config.Bind<Controller>().ToSelf();
var resolver = config.ToResolver();
var controller = resolver.Get<Controller>();
Supported binding syntax.
- Bind
- To
// Type IService to Service Type instance
config.Bind<IService>().To<Service>();
- ToSelf
// Type Controller to Controller Type instance
config.Bind<Controller>().ToSelf();
- ToMethod
// Type IScheduler to factory method
config.Bind<IScheduler>().ToMethod(x => x.Get<ISchedulerFactory>().GetScheduler());
- ToConstant
// Type Messenger to instance
config.Bind<Messenger>().ToConstant(Messenger.Default);
- InTransientScope
- InSingletonScope
- InScope
- Named
- WithConstructorArgument
- WithPropertyValue
- WithMetadata
Supported scope.
- New instance created each time
- Lifecycle is not managed by resolver
config.Bind<TransientObject>().ToSelf().InTransientScope();
or
config.Bind<TransientObject>().ToSelf();
- Single instance created and same instance returned
- Lifecycle managed by resolver (IScopeStorage) and Dispose called when resolver disposed
config.Bind<SingletonObject>().ToSelf().InSingletonScope();
- You can create a custom scope
config.Bind<CustomeScopeObject>().ToSelf().InScope(new CustomeScope());
Prepared by standard.
Naming constraint for lookup binding.
public class Child
{
}
public class Parent
{
pulbic Child Child { get; }
public Parent([Named("foo")] Child child)
{
Child = child;
}
}
// Usage
var config = new ResolverConfig();
config.Bind<Child>().ToSelf().InSingletonScope().Named("foo");
config.Bind<Child>().ToSelf().InSingletonScope().Named("bar");
config.Bind<Parent>().ToSelf();
var resolver = config.ToResolver();
var parent = resolver.Get<Parent>();
var foo = resolver.Get<Child>("foo");
var bar = resolver.Get<Child>("bar");
Debug.Assert(parent.Child == foo);
Debug.Assert(parent.Child != bar);
Mark of property injection target or select constructor.
public class HasPropertyObject
{
[Inject]
public Target Target { get; set; }
}
Set constructor argument or property value.
public class Sceduler
{
public Sceduler(ITimer timer, int timeout)
{
}
}
// Usage
config.Bind<ITimer>().To<Timer>().InSingletonScope();
config.Bind<Sceduler>().ToSelf().InSingletonScope().WithConstructorArgument("timeout", 30);
StandardResolver is constructed from sub-components. Change the sub-components in ResolverConfig, can be customized StandardResolver.
// Add custom processor to pipeline
public sealed class CustomInitializeProcessor : IProcessor
{
public void Initialize(object instance)
{
...
}
}
config.UseProcessor<CustomInitializeProcessor>();
// Add custome scope and storage
public sealed class CustomScopeStorage : IScopeStorage
{
...
}
public sealed class CustomScope : IScope
{
public IScopeStorage GetStorage(IKernel kernel)
{
return kernel.Components.Get<CustomScopeStorage>();
}
}
config.Components.Add<CustomScopeStorage>();
config.Bind<SimpleObject>().ToSelf().InScope(new CustomScope());
Ohter topics.
If the class implements Initializable, Initialized called after construct.
protected class InitializableObject : IInitializable
{
public bool Initialized { get; private set; }
public void Initialize()
{
Initialized = true;
}
}
// Usage
config.Bind<InitializableObject>().ToSelf().InSingletonScope();
var obj = resolver.Get<InitializableObject>();
Debug.Assert(obj.Initialized);
If custom constraints want is as follows:
// Create IConstraint implement
public sealed class HasMetadataConstraint : IConstraint
{
public string Key { get; }
public HasMetadataConstraint(string key)
{
Key = key;
}
public bool Match(IBindingMetadata metadata)
{
return metadata.Has(Key);
}
}
// Create ConstraintAttribute derived class
public sealed class HasMetadataAttribute : ConstraintAttribute
{
public string Key { get; }
public HasMetadataAttribute(string key)
{
Key = key;
}
public override IConstraint CreateConstraint()
{
return new HasMetadataConstraint(Key);
}
}
// Usage
public class Parent
{
pulbic Child Child { get; }
public Parent([HasMetadata("hoge")] Child child)
{
Child = child;
}
}
config.Bind<Child>().ToSelf().InSingletonScope();
config.Bind<Child>().ToSelf().InSingletonScope().WithMetadata("hoge", null);
config.Bind<Parent>().ToSelf();
- AOP( ゚д゚)、ペッ
- Method Injection (I don't need)
- Request scope (supported by Smart.Resolver.AspNetCore)
- Circular reference detection (Your design bug)