I know that Concrete Types can be configured with Structure Map the following way:
ForRequestedType<Rule>().TheDefault.Is.Object(new ColorRule("Green"));
This works if you know the type ahead of time. I want to do it at run time, and there does not seem to be a way. Can some one enlighten me? What I want to do is something like the following: (This appears to be not supported by structure map)
ForRequestedType(typeof(Rule)).TheDefault.Is.Object(new ColorRule("Green"));
The reason for this is because I'm working on a wrapper for structure-map's configuration. And I will not know the type ahead of time. For the .Object(new ColorRule("Green")) I am going to be passing in a delegate instead, which would actually construct the object on request.
Recently Jeremy added the ability to configure a Func as a builder for your type. Here is an example of using a delegate/lambda as your builder.
public interface IRule
{
string Color { get; set; }
}
public class ColorfulRule : IRule
{
public string Color { get; set; }
public ColorfulRule(string color)
{
Color = color;
}
}
[TestFixture]
public class configuring_delegates
{
[Test]
public void test()
{
var color = "green";
Func<IRule> builder = () => new ColorfulRule(color);
var container = new Container(cfg=>
{
cfg.For<IRule>().Use(builder);
});
container.GetInstance<IRule>().Color.ShouldEqual("green");
color = "blue";
container.GetInstance<IRule>().Color.ShouldEqual("blue");
}
}
Related
Using Guice,I would like create three different instances for my Color class i.e BLUE, RED, YELLOW and want to bind different color value... but I am not understanding how to bind different value per instance...
For the below sample code, if you see, I would like to use same ColorClass implementation for all three colors Instances(named as "BLUE","RED","ORANGE") by passing different color as String variable.
public interface ColorInterface {
public String getMeColor()
}
Sample implementation....
public class ColorClass implements ColorInterface {
#Inject #Named("color")
String color
public String getMeColor(){
return color
}
}
Sample binding........
public class ColorModule extends AbstractModule {
#Override
protected void configure() {
bind(ColorInterface.class).annotatedWith(Names.named("BLUE")).to(ColorClass.class);
bind(ColorInterface.class).annotatedWith(Names.named("RED")).to(ColorClass.class);
bind(ColorInterface.class).annotatedWith(Names.named("ORANGE")).to(ColorClass.class);
......
}
}
Please help me...
If this directly is your issue, I would suggest a slight change in the implementation to move the injected #Named("color") String into a constructor argument and the use of a custom Provider:
public class ColorClass implements ColorInterface {
String color;
ColorClass(String color) {
this.color = color;
}
public String getMeColor(){
return color;
}
public static Provider implements Provider<ColorClass> {
String color;
public Provider(String color) {
this.color = color;
}
public ColorClass get() {
return new ColorClass(color);
}
}
}
and then in your module:
public class ColorModule extends AbstractModule {
#Override
protected void configure() {
bind(ColorInterface.class).annotatedWith(Names.named("BLUE"))
.toProvider(new ColorClass.Provider("Blue"));
bind(ColorInterface.class).annotatedWith(Names.named("RED"))
.toProvider(new ColorClass.Provider("Red"));
bind(ColorInterface.class).annotatedWith(Names.named("ORANGE"))
.toProvider(new ColorClass.Provider("Orange"));
}
}
Obviously, the Provider doesn't need to be a static inner class like I did there, just something in the same package.
In case this exact problem isn't really your problem and you really do need #Named("color") String to be differently injected (say, you've actually got some really deep nested structure pulled together with guice and need a different binding deep in the hierarchy, and can't easily refactor that into a constructor parameter), then you'll need to use private modules.
However, that technique is vast overkill for the case you presented, so I'm hesitant to dive into it here. It's really a rather advanced topic you shouldn't try to tackle unless you really need to solve the problem it solves. (The problem is sometimes referred to as the "Robot Arms" problem)
Structuremap experts,
I found this post on stackoverflow ...
Passing constructor arguments when using StructureMap
Someone suggested to use the StructureMap configuration with runtime value like this
For<IProductProvider>().Use<ProductProvider>.Ctor<string>("connectionString").Is(someValueAtRunTime);
But example is not adequate enough to understand its declaration and usage. I try to find on StructureMap site as well but not much help ...
In my situation, I want to pass on the dependency of concrete DbContext (IDbContext) to the constructor of the class with connection string dynamically created during run time within that class.
Finally I managed to make it working ...
Here how I did it ...
Hope it will help someone, and thanks to PHeiberg for answer me before and showing me right direction.
Interface Definition
public interface ICreditCard
{
string GetName();
}
public interface IAdditionalCreditCard : ICreditCard
{
}
public class AdditionalCreditCard : IAdditionalCreditCard
{
private readonly string _name;
public AdditionalCreditCard(string name)
{
_name = name;
}
public string GetName()
{
return _name;
}
}
Define function in Structure map config code
Func<string, IAdditionalCreditCard> additionalCreditCard = value =>
ObjectFactory.With("name").EqualTo(value).GetInstance<AdditionalCreditCard>();
Add following configuration in ObjectFactory.Configure
ObjectFactory.Configure(config =>
{
config.For<Func<string, IAdditionalCreditCard>>().Use(additionalCreditCard);
});
And in code ...
public class PaymentSystem
{
private readonly Func<string, IAdditionalCreditCard> _addtionalCreditCard;
private IAdditionalCreditCard _addCreditCard;
public PaymentSystem(Func<string, IAdditionalCreditCard> additionalCredit)
{
_addtionalCreditCard = additionalCredit;
}
public string AddtionalSystemType()
{
_addCreditCard = _addtionalCreditCard("American Express");
return _addCreditCard.GetName();
}
}
The code you are posting is supposed to go in the setup code for StructureMap, which can go in the Initialize/Configure method or a Registry. The setup code is normally executed only once in the application's life cycle. So if you know the connection string value when the application is stared and you configure StructureMap, you can put the code you posted in the initialization of StructureMap. If the value is not known until later on, you need some kind of factory approach.
A factory approach could be done like this (in your StructureMap configuration code):
Func<string, IDbContext> createContext = value => {
/* create context based on value */
};
ObjectFactory.Initialize(c => {
For<Func<string, IDbContext>>().Use(createContext);
// The rest of you configuration ...
});
You can now use the Func to create an instance of the context when you need it:
public class ProductProvider : IProductProvider
{
private readonly Func<string, IDbContext> _contextCreator;
public ProductProvider(Func<string, IDbContext> contextCreator)
{
_contextCreator = contextCreator;
}
public IEnumerable<Product> GetProducts(string someValue)
{
using(var context = contextCreator(someValue))
{
return SomeOperationOnThe(context);
}
}
}
I am about to switch from Windsor to Structuremap for an existing project with ~100 registered components (mostly singletons).
All components inherit from a common base class that provides logging and health tracking and for this reason, contains a "Name" property used to identify component instances.
With Windsor, it was possible to set the component's Name property to the name that was used to register the component in the IOC container (We used a Facility for this).
My question: Is something like this possible with Structuremap?
(I dream of a call to c.For<IFoo>.Use<Bar>.Named("Doe") that magically results in instanceOfBar.Name = "Doe" somewhere.)
Here is what I tried:
using System;
using StructureMap;
using StructureMap.Interceptors;
using System.Diagnostics;
namespace ConsoleApplication1
{
interface IServiceA { }
interface IServiceB { }
class Base
{
public string Name { get; set; }
}
class ComponentA : Base, IServiceA { }
class ComponentB : Base, IServiceB
{
public ComponentB(IServiceA serviceA)
{
this.ServiceA = serviceA;
}
public IServiceA ServiceA { get; private set; }
}
class SetNameInterceptor : TypeInterceptor
{
public bool MatchesType(Type type) { return true; }
public object Process(object target, IContext context)
{
// *** Any other way? This does not work...
string name = context.BuildStack.Current != null ? context.BuildStack.Current.Name : context.RequestedName;
((Base)target).Name = name;
return target;
}
}
class Program
{
static void Main(string[] args)
{
Container container = new Container(c =>
{
c.RegisterInterceptor(new SetNameInterceptor());
c.For<IServiceA>().Use<ComponentA>().Named("A");
c.For<IServiceB>().Use<ComponentB>().Named("B");
});
var b = container.GetInstance<IServiceB>();
// both Fail:
Debug.Assert(((ComponentB)b).Name == "B");
Debug.Assert(((ComponentA)((ComponentB)b).ServiceA).Name == "A");
}
}
}
The above obviously does not work, I tried several variations but had no luck. The registered name of the target object does not seem to be consistently reachable via IContext.
My second best approach would be to define a new "NamedComponent(...)" extension method that resolves to Named(name).WithProperty(x => x.Name).EqualTo(name), but I wonder if this can be avoided to keep component registration as "structuremap-like" as possible?
Am I missing something?
I've never used WithProperty before but if it works the way I'd expect it should do the trick for you.
I think I would favor using EnrichWith though. Something like:
c.For<IFoo>().Use<Foo>().Named(name).EnrichWith(f => f.Name = name);
EnrichWith is a bit more explicit about what it's doing IMO, and lets you call any code on your instance before returning it to the caller. I like that this lets you do a straightforward assignment as well.
There is also a more complex handler you can use with EnrichWith that gives access to the context of the request - this would allow you to do something like this:
c.For<IFoo>().Use<Foo>().Named(name)
.EnrichWith((c, i) => {
i.Name = c.RequestedName;
return i;
});
This may be overkill for your situation but the contextual awareness can be pretty useful.
I have an enumeration which I'd like to persist as a value of some sort into the underlying database so that I can bring it back and forth.
I have read some articles that suggest to create a enumeration wrapper with static implicit operators defined, mapped using a ComplexType object mapping as described in the link below.
How to fake Enums in EF4
This solution works flawlessly! My thanks to Alex James.
Aside, I discovered of the EnumDataTypeAttribute Class which purpose seems to handle enums persistence through Entity Framework. I tried it and it doesn't seem to work at all. Here's a code sample.
public enum StreetDirection {
East
, None
, North
, NorthEast
, NorthWest
, South
, SouthEast
, SouthWest
, West
}
public enum StreetType {
Avenue
, Boulevard
, Court
, Crescent
, Drive
, Hill
, None
, Road
, Street
}
public class StreetTypeWrapper {
public int Value {
get {
return (int)t;
}
set {
t = (StreetType)value;
}
}
public StreetType EnumValue {
get {
return t;
}
set {
t = value;
}
}
public static implicit operator int(StreetTypeWrapper w) {
return w.Value;
}
public static implicit operator StreetType(StreetTypeWrapper w) {
return w == null ? StreetType.None : w.EnumValue;
}
public static implicit operator StreetTypeWrapper(int i) {
return new StreetTypeWrapper() { Value = i };
}
public static implicit operator StreetTypeWrapper(StreetType t) {
return new StreetTypeWrapper() { EnumValue = t };
}
private StreetType t;
}
public class Street {
[EnumDataType(typeof(StreetDirection))]
public StreetDirection Direction { get; set; }
public string Name { get; set; }
public int StreetId { get; set; }
public StreetTypeWrapper Type { get; set; }
}
public class StreetTypeMapping
: ComplexTypeConfiguration<StreetTypeWrapper> {
public StreetTypeMapping() {
Property(o => o.Value)
.HasColumnName("StreetType");
}
}
Now, if I believe and/or understanding correctly what MSDN says about the EnumDataTypeAttribute class, the Direction property should get persisted into the database. Well, it doesn't! I can't find a reason for this, except that EF doesn't support enums persistence. As for the StreetTypeWrapper and its StreetTypeMapping class, it does work flawlessly.
Are there any clue why the EnumDataType shouldn't work as expected?
This is because of design flaw in .NET framework. .NET framework contains famous System.ComponentModel.DataAnnotations namespace where multiple different attributes are defined. Many different parts of .NET framework are using this namespace but they are using it to achieve different tasks and every such part use only some subset of attributes. This causes a lot of confusion.
EnumDataTypeAttribute is such example. This attribute is only for ASP.NET Dynamic Data. It allows you to mark int property with this attribute and automatically generated UI will show drop down with enum values instead of textbox for numeric values. So there is mapping from enum to int but it is in UI layer not in model / persistence layer.
How do I handle classes with static methods with Ninject?
That is, in C# one can not have static methods in an interface, and Ninject works on the basis of using interfaces?
My use case is a class that I would like it to have a static method to create an
unpopulated instance of itself.
EDIT 1
Just to add an example in the TopologyImp class, in the GetRootNodes() method, how would I create some iNode classes to return? Would I construct these with normal code practice or would I somehow use Ninject? But if I use the container to create then haven't I given this library knowledge of the IOC then?
public interface ITopology
{
List<INode> GetRootNodes();
}
public class TopologyImp : ITopology
{
public List<INode> GetRootNodes()
{
List<INode> result = new List<INode>();
// Need code here to create some instances, but how to without knowledge of the container?
// e.g. want to create a few INode instances and add them to the list and then return the list
}
}
public interface INode
{
// Parameters
long Id { get; set; }
string Name { get; set; }
}
class NodeImp : INode
{
public long Id
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public string Name
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
}
// Just background to highlight the fact I'm using Ninject fine to inject ITopology
public partial class Form1 : Form
{
private ITopology _top;
public Form1()
{
IKernel kernal = new StandardKernel(new TopologyModule());
_top = kernal.Get<ITopology>();
InitializeComponent();
}
}
If you're building a singleton or something of that nature and trying to inject dependencies, typically you instead write your code as a normal class, without trying to put in lots of (probably incorrect) code managing the singleton and instead register the object InSingletonScope (v2 - you didnt mention your Ninject version). Each time you do that, you have one less class that doesnt surface its dependencies.
If you're feeling especially bloody-minded and are certain that you want to go against that general flow, the main tools Ninject gives you is Kernel.Inject, which one can use after you (or someone else) has newd up an instance to inject the dependencies. But then to locate one's Kernelm you're typically going to be using a Service Locator, which is likely to cause as much of a mess as it is likely to solve.
EDIT: Thanks for following up - I see what you're after. Here's a hacky way to approximate the autofac automatic factory mechanism :-
/// <summary>
/// Ugly example of a not-very-automatic factory in Ninject
/// </summary>
class AutomaticFactoriesInNinject
{
class Node
{
}
class NodeFactory
{
public NodeFactory( Func<Node> createNode )
{
_createNode = createNode;
}
Func<Node> _createNode;
public Node GenerateTree()
{
return _createNode();
}
}
internal class Module : NinjectModule
{
public override void Load()
{
Bind<Func<Node>>().ToMethod( context => () => Kernel.Get<Node>() );
}
}
[Fact]
public void CanGenerate()
{
var kernel = new StandardKernel( new Module() );
var result = kernel.Get<NodeFactory>().GenerateTree();
Assert.IsType<Node>( result );
}
}
The ToMethod stuff is a specific application of the ToProvider pattern -- here's how you'd do the same thing via that route:-
...
class NodeProvider : IProvider
{
public Type Type
{
get { return typeof(Node); }
}
public object Create( IContext context )
{
return context.Kernel.Get<Node>();
}
}
internal class Module : NinjectModule
{
public override void Load()
{
Bind<Func<Node>>().ToProvider<NodeProvider>();
}
}
...
I have not thought this through though and am not recommending this as A Good Idea - there may be far better ways of structuring something like this. #Mark Seemann? :P
I believe Unity and MEF also support things in this direction (keywords: automatic factory, Func)
EDIT 2: Shorter syntax if you're willing to use container-specific attributes and drop to property injection (even if Ninject allows you to override the specific attributes, I much prefer constructor injection):
class NodeFactory
{
[Inject]
public Func<Node> NodeFactory { private get; set; }
public Node GenerateTree()
{
return NodeFactory();
}
}
EDIT 3: You also need to be aware of this Ninject Module by #Remo Gloor which is slated to be in the 2.4 release
EDIT 4: Also overlapping, but not directly relevant is the fact that in Ninject, you can request an IKernel in your ctor/properties and have that injected (but that doesn't work directly in a static method).