Structure Map Generic Type Scanner - structuremap

High Level
With StructureMap, Can I define a assembly scan rule that for an interface IRequestService<T> will return the object named TRequestService
Examples:
FooRequestService is injected when IRequestService<FooRequest> is requested
BarRequestService is injected when IRequestService<BarRequest> is requested
Details
I have a generic interface defined
public interface IRequestService<T> where T : Request
{
Response TransformRequest(T request, User current);
}
and then I have multiple Request objects that implement this interface
public class FooRequestService : IRequestService<Foo>
{
public Response TransformRequest(Foo request, User current) { ... }
}
public class BarRequestService : IRequestService<Bar>
{
public Response TransformRequest(Bar request, User current) { ... }
}
Now I am at the point where I need to register these classes so that StructureMap knows how to create them because in my controller I want have the following ctor (which I want StructureMap to inject a FooRequestService into)
public MyController(IRequestService<Foo> fooRequestService) { ... }
Right now to get around my issue I have implemented an empty interface and instead of having the FooRequestService implement the generic interface I have it implement this empty interface
public interface IFooRequestService : IRequestService<Foo> { }
Then my controllers ctor looks like so, which works with StructureMaps' Default Convention Scanner
public MyController(IFooRequestService fooRequestService) { ... }
How could I create a rule with StructureMap's assembly scanner to register all objects named TRequestService with IRequestService<T> (where T = "Foo", "Bar", etc) so that I don't have to create these empty Interface definitions?
To throw something else into the mix, where I am handling StructureMap's assembly scanning does not have any reference to the assembly that defines IRequestService<T> so this has to use some sort of reflection when doing this. I scanned the answer to "StructureMap Auto registration for generic types using Scan" but it seems as though that answer requires a reference to the assembly that contains the interface definition.
I am on the path of trying to write a custom StructureMap.Graph.ITypeScanner but I am kind of stuck on what to do there (mainly because I have little experience with reflection).

You are on the right path with the scanner. Thankfully there is one built into StructureMap. Unfortunately it is not yet, as of this writing, released. Get the latest from trunk and you will see a few new things available within the scanner configuration. An example for your needs is below.
public class MyRegistry : Registry
{
public MyRegistry()
{
Scan(x =>
{
x.TheCallingAssembly();
//x.AssembliesFromApplicationBaseDirectory();
x.WithDefaultConventions();
x.ConnectImplementationsToTypesClosing(typeof (IRequestService<>));
});
}
}
First you need to tell the scanner configuration which assemblies to include in the scan. The commented AssembliesFromApplicationBaseDirectory() method also might help if you are not doing a registry per assembly.
To get your generic types into the container use ConnectImplementationsToTypesClosing.
For an example on how to setup use registries when setting up the container see:
http://structuremap.sourceforge.net/ConfiguringStructureMap.htm
If you like you can skip using registries in general and just do a scan within ObjectFactory.Initialize.
Hope this helps.

Related

Discovering Generic Controllers in ASP.NET Core

I am trying to create a generic controller like this:
[Route("api/[controller]")]
public class OrdersController<T> : Controller where T : IOrder
{
[HttpPost("{orderType}")]
public async Task<IActionResult> Create(
[FromBody] Order<T> order)
{
//....
}
}
I intend for the {orderType} URI segment variable to control the generic type of the controller. I'm experimenting with both a custom IControllerFactory and IControllerActivator, but nothing is working. Every time I try to send a request, I get a 404 response. The code for my custom controller factory (and activator) is never executed.
Evidently the problem is that ASP.NET Core expects valid controllers to end with the suffix "Controller", but my generic controller instead has the (reflection based) suffix "Controller`1". Thus the attribute-based routes it declares are going unnoticed.
In ASP.NET MVC, at least in its early days, the DefaultControllerFactory was responsible for discovering all the available controllers. It tested for the "Controller" suffix:
The MVC framework provides a default controller factory (aptly named DefaultControllerFactory) that will search through all the assemblies in an appdomain looking for all types that implement IController and whose name ends with "Controller."
Apparently, in ASP.NET Core, the controller factory no longer has this responsibility. As I stated earlier, my custom controller factory executes for "normal" controllers, but is never invoked for generic controllers. So there is something else, earlier in the evaluation process, which governs the discovery of controllers.
Does anyone know what "service" interface is responsible for that discovery? I don't know the customization interface or "hook" point.
And does anyone know of a way to make ASP.NET Core "dump" the names of all the controllers it discovered? It would be great to write a unit test that verifies that any custom controller discovery I expect is indeed working.
Incidentally, if there is a "hook" which allows generic controller names to be discovered, it implies that route substitutions must also be normalized:
[Route("api/[controller]")]
public class OrdersController<T> : Controller { }
Regardless of what value for T is given, the [controller] name must remain a simple base-generic name. Using the above code as an example, the [controller] value would be "Orders". It would not be "Orders`1" or "OrdersOfSomething".
Note
This problem could also be solved by explicitly declaring the closed-generic types, instead of generating them at run time:
public class VanityOrdersController : OrdersController<Vanity> { }
public class ExistingOrdersController : OrdersController<Existing> { }
The above works, but it produces URI paths that I don't like:
~/api/VanityOrders
~/api/ExistingOrders
What I had actually wanted was this:
~/api/Orders/Vanity
~/api/Orders/Existing
Another adjustment gets me the URI's I'm looking for:
[Route("api/Orders/Vanity", Name ="VanityLink")]
public class VanityOrdersController : OrdersController<Vanity> { }
[Route("api/Orders/Existing", Name = "ExistingLink")]
public class ExistingOrdersController : OrdersController<Existing> { }
However, although this appears to work, it does not really answer my question. I would like to use my generic controller directly at run-time, rather than indirectly (via manual coding) at compile-time. Fundamentally, this means I need ASP.NET Core to be able to "see" or "discover" my generic controller, despite the fact that its run-time reflection name does not end with the expected "Controller" suffix.
What happens by default
During the controller discovery process, your open generic Controller<T> class will be among the candidate types. But the default implementation of the IApplicationFeatureProvider<ControllerFeature> interface, DefaultControllerTypeProvider, will eliminate your Controller<T> because it rules out any class with open generic parameters.
Why overriding IsController() doesn't work
Replacing the default implementation of the IApplicationFeatureProvider<ControllerFeature> interface, in order to override DefaultControllerTypeProvider.IsController(), will not work. Because you don't actually want the discovery process to accept your open generic controller (Controller<T>) as a valid controller. It is not a valid controller per se, and the controller factory wouldn't know how to instantiate it anyway, because it wouldn't know what T is supposed to be.
What needs to be done
1. Generate closed controller types
Before the controller discovery process even starts, you need to generate closed generic types from your open generic controller, using reflection. Here, with two sample entity types, named Account and Contact:
Type[] entityTypes = new[] { typeof(Account), typeof(Contact) };
TypeInfo[] closedControllerTypes = entityTypes
.Select(et => typeof(Controller<>).MakeGenericType(et))
.Select(cct => cct.GetTypeInfo())
.ToArray();
We now have closed TypeInfos for Controller<Account> and Controller<Contact>.
2. Add them to an application part and register it
Application parts are usually wrapped around CLR assemblies, but we can implement a custom application part providing a collection of types generated at runtime. We simply need to have it implement the IApplicationPartTypeProvider interface. Therefore, our runtime-generated controller types will enter the controller discovery process like any other built-in type would.
The custom application part:
public class GenericControllerApplicationPart : ApplicationPart, IApplicationPartTypeProvider
{
public GenericControllerApplicationPart(IEnumerable<TypeInfo> typeInfos)
{
Types = typeInfos;
}
public override string Name => "GenericController";
public IEnumerable<TypeInfo> Types { get; }
}
Registration in MVC services (Startup.cs):
services.AddMvc()
.ConfigureApplicationPartManager(apm =>
apm.ApplicationParts.Add(new GenericControllerApplicationPart(closedControllerTypes)));
As long as your controller derives from the built-in Controller class, there is no actual need to override the IsController method of the ControllerFeatureProvider. Because your generic controller inherits the [Controller] attribute from ControllerBase, it will be accepted as a controller in the discovery process regardless of its somewhat bizarre name ("Controller`1").
3. Override the controller name in the application model
Nevertheless, "Controller`1" is not a good name for routing purposes. You want each of your closed generic controllers to have independent RouteValues. Here, we will replace the name of the controller with that of the entity type, to match what would happen with two independent "AccountController" and "ContactController" types.
The model convention attribute:
public class GenericControllerAttribute : Attribute, IControllerModelConvention
{
public void Apply(ControllerModel controller)
{
Type entityType = controller.ControllerType.GetGenericArguments()[0];
controller.ControllerName = entityType.Name;
}
}
Applied to the controller class:
[GenericController]
public class Controller<T> : Controller
{
}
Conclusion
This solution stays close to the overall ASP.NET Core architecture and, among other things, you will keep full visibility of your controllers through the API Explorer (think "Swagger").
It has been tested successfully with both conventional and attribute-based routing.
Short Answer
Implement IApplicationFeatureProvider<ControllerFeature>.
Question and Answer
Does anyone know what "service" interface is responsible for [discovering all available controllers]?
The ControllerFeatureProvider is responsible for that.
And does anyone know of a way to make ASP.NET Core "dump" the names of all the controllers it discovered?
Do that within ControllerFeatureProvider.IsController(TypeInfo typeInfo).
Example
MyControllerFeatureProvider.cs
using System;
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Mvc.Controllers;
namespace CustomControllerNames
{
public class MyControllerFeatureProvider : ControllerFeatureProvider
{
protected override bool IsController(TypeInfo typeInfo)
{
var isController = base.IsController(typeInfo);
if (!isController)
{
string[] validEndings = new[] { "Foobar", "Controller`1" };
isController = validEndings.Any(x =>
typeInfo.Name.EndsWith(x, StringComparison.OrdinalIgnoreCase));
}
Console.WriteLine($"{typeInfo.Name} IsController: {isController}.");
return isController;
}
}
}
Register it during startup.
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvcCore()
.ConfigureApplicationPartManager(manager =>
{
manager.FeatureProviders.Add(new MyControllerFeatureProvider());
});
}
Here is some example output.
MyControllerFeatureProvider IsController: False.
OrdersFoobar IsController: True.
OrdersFoobarController`1 IsController: True.
Program IsController: False.
<>c__DisplayClass0_0 IsController: False.
<>c IsController: False.
And here is a demo on GitHub. Best of luck.
Edit - Adding Versions
.NET Version
> dnvm install "1.0.0-rc2-20221" -runtime coreclr -architecture x64 -os win -unstable
NuGet.Config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear/>
<add key="AspNetCore"
value="https://www.myget.org/F/aspnetvnext/api/v3/index.json" />
</packageSources>
</configuration>
.NET CLI
> dotnet --info
.NET Command Line Tools (1.0.0-rc2-002429)
Product Information:
Version: 1.0.0-rc2-002429
Commit Sha: 612088cfa8
Runtime Environment:
OS Name: Windows
OS Version: 10.0.10586
OS Platform: Windows
RID: win10-x64
Restore, Build, and Run
> dotnet restore
> dotnet build
> dotnet run
Edit - Notes on RC1 vs RC2
This might not be possible is RC1, because DefaultControllerTypeProvider.IsController() is marked as internal.
Application Feature Providers examine application parts and provide features for those parts. There are built-in feature providers for the following MVC features:
Controllers
Metadata Reference
Tag Helpers
View Components
Feature providers inherit from IApplicationFeatureProvider, where T is the type of the feature. You can implement your own feature providers for any of MVC's feature types listed above. The order of feature providers in the ApplicationPartManager.FeatureProviders collection can be important, since later providers can react to actions taken by previous providers.
By default, ASP.NET Core MVC ignores generic controllers (for example, SomeController). This sample uses a controller feature provider that runs after the default provider and adds generic controller instances for a specified list of types (defined in EntityTypes.Types):
public class GenericControllerFeatureProvider : IApplicationFeatureProvider<ControllerFeature>
{
public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllerFeature feature)
{
// This is designed to run after the default ControllerTypeProvider,
// so the list of 'real' controllers has already been populated.
foreach (var entityType in EntityTypes.Types)
{
var typeName = entityType.Name + "Controller";
if (!feature.Controllers.Any(t => t.Name == typeName))
{
// There's no 'real' controller for this entity, so add the generic version.
var controllerType = typeof(GenericController<>)
.MakeGenericType(entityType.AsType()).GetTypeInfo();
feature.Controllers.Add(controllerType);
}
}
}
}
The entity types:
public static class EntityTypes
{
public static IReadOnlyList<TypeInfo> Types => new List<TypeInfo>()
{
typeof(Sprocket).GetTypeInfo(),
typeof(Widget).GetTypeInfo(),
};
public class Sprocket { }
public class Widget { }
}
The feature provider is added in Startup:
services.AddMvc()
.ConfigureApplicationPartManager(p =>
p.FeatureProviders.Add(new GenericControllerFeatureProvider()));
By default, the generic controller names used for routing would be of the form GenericController`1[Widget] instead of Widget. The following attribute is used to modify the name to correspond to the generic type used by the controller:
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using System;
namespace AppPartsSample
{
// Used to set the controller name for routing purposes. Without this convention the
// names would be like 'GenericController`1[Widget]' instead of 'Widget'.
//
// Conventions can be applied as attributes or added to MvcOptions.Conventions.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class GenericControllerNameConvention : Attribute, IControllerModelConvention
{
public void Apply(ControllerModel controller)
{
if (controller.ControllerType.GetGenericTypeDefinition() !=
typeof(GenericController<>))
{
// Not a GenericController, ignore.
return;
}
var entityType = controller.ControllerType.GenericTypeArguments[0];
controller.ControllerName = entityType.Name;
}
}
}
The GenericController class:
using Microsoft.AspNetCore.Mvc;
namespace AppPartsSample
{
[GenericControllerNameConvention] // Sets the controller name based on typeof(T).Name
public class GenericController<T> : Controller
{
public IActionResult Index()
{
return Content($"Hello from a generic {typeof(T).Name} controller.");
}
}
}
Sample: Generic controller feature
To get a list of controllers in RC2, just get ApplicationPartManager from DependencyInjection and do this:
ApplicationPartManager appManager = <FROM DI>;
var controllerFeature = new ControllerFeature();
appManager.PopulateFeature(controllerFeature);
foreach(var controller in controllerFeature.Controllers)
{
...
}

StructureMap: How to send the container to a class that has a Constructor that does not accept Parameters

I am trying to find out how I can pass the StructrueMap container to a class that I wrote that inherits from another (MS-Class).
namespace TheNamespace
{
public class DatabaseIssuerNameRegistry : ValidatingIssuerNameRegistry
{
/* **This can't be done**
public DatabaseIssuerNameRegistry(IPortalTenantManager portalTenantManager)
{
_someField= portalTenantManager;
}*/
protected override bool IsThumbprintValid(string thumbprint, string issuer)
{
//How does it work ???????????
var portalTenantManager = container.GetInstance<IPortalTenantManager>();
//Do something with the portalTenantManager
}
}
I need portalTenantManager to be the Instance that I have defined in my container in the Global.asax.
My Global Assax has these things setup:
protected void Application_Start()
{
var container = new Container();
container.Configure(x =>
{ ....
....
x.For<IPortalTenantManager>().Use<PortalTenantManager>();
});
...
...
ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory(container));
...
GlobalConfiguration.Configuration.DependencyResolver = new StructureMapApiControllerFactory(container);
...
}
Edit:
Because of the comments of #NightOwl888 I'll explain a bit further what this class does. (Hopefully explaining so why my hands are tied)
My application is able to authenticate a user with Azure Active Directory and is Multi-tenant capable. In the authentication pipeline I have the possibility to store the validation endpoints in my database instead of the default way on the web.config file. See MSDN
and this, which actually is explaining exactly what I'm doing.
So I registered my class in the web.config under the Tag issuerNameRegistry. At some point of the validation pipeline my class is instantiated and the overriden method IsThumbprintValid is beeing called. The problem is that the class registered in issuerNameRegistry expects a parameterless constructor (there it is! the constrained construction!), therefore I cannot create a constructor that would solve my problem.
Thanks for your help
It turns out that this question has been asked before on MSDN, the answer of which was provided by Travis Spencer in 2 different posts.
it is typical in my experience to have a single container and use that service- or Web-side-wide. In the startup of the service or Web app, you can create the container, register the dependencies, new up an instance of your SecurityTokenServiceConfiguration class, resolve your dependencies, use it to punch out a SecurityTokenService object, and host it.
After the first beta, we really pushed for DI support. We got a little hook in beta 2. You can now create a custom SecurityTokenServiceConfiguration class that overrides the virtual CreateSecurityTokenService method. The implementation in Microsoft's SecurityTokenServiceConfiguration does Activator.CreateInstance; yours can do IoC. This can include the resolution of an IssuerNameRegistiry. Something like this perhaps:
RequestSecurityTokenResponse Issue(IClaimsPrincipal principal, RequestSecurityToken request)
{
SecurityTokenServiceConfiguration config = new MyGoodSecurityTokenServiceConfiguration();
SecurityTokenService sts = config.CreateSecurityTokenService();
RequestSecurityTokenResponse rstr = sts.Issue(principal, request);
return rstr;
}
public class MyGoodSecurityTokenServiceConfiguration : SecurityTokenServiceConfiguration
{
public override SecurityTokenService CreateSecurityTokenService()
{
IssuerNameRegistry = IoC.Resolve<IssuerNameRegistry>();
var sts = IoC.Reslove<SecurityTokenService>();
return sts;
}
}
Of course, this means that you need to create a static instance of your DI container so it is accessible to your SecurityTokenServiceConfiguration class. Personally, I don't like that idea because it makes your DI container accessible throughout the application, which can lead to abuse of the DI container as a service locator.
Ideally, there would be a way in any DI friendly framework to pass the container into an abstract factory in order to resolve service dependencies. However, since I am not familiar with WIF it is unclear whether that can be done - perhaps the class where the Issue method exists could have a constructor added? The trick is to keep walking up the chain until you find the first place in the framework where you can intervene and do all of your DI configuration there.

Resolving a type without registering first - prism 4 and Untiy

First of all I would like to remark I am new with the concept of prism, DI and containers. I am looking on one of the code samples provided with the Prism Library:
The code simply injects a view with the "Hello World" string (in a TextBlock element) to a region in the shell.
When the application starts-up, it creates a new BootStrapper instance, which creates and initializes the shell:
public class Bootstrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
return Container.Resolve<Shell>();
}
protected override void InitializeShell()
{
base.InitializeShell();
Application.Current.RootVisual = (UIElement)this.Shell;
}
protected override void ConfigureModuleCatalog()
{
base.ConfigureModuleCatalog();
ModuleCatalog moduleCatalog = (ModuleCatalog)this.ModuleCatalog;
moduleCatalog.AddModule(typeof(HelloWorldModule.HelloWorldModule));
}
}
My question refers to the method CreateShell(). I couldnt find nowhere in the supplied code (including not in a configuration file or any xaml file...) where do they register the type Shell, and even if it was registered - the supplies Shell class doesnt implement any interface... what is the meaning of resolving a specific type?
the Shell implementation:
public partial class Shell : UserControl
{
public Shell()
{
InitializeComponent();
}
}
This looks like a magic to me, so I tried to create my own type (MyType) and resolve it the same way:
Container.Resolve<MyType>();
By setting a breakepoint inside MyType constructor, I saw that it DID resolved MyType. Can somebody please explain to me how does it work?
These couple of threads should answer your question:
http://compositewpf.codeplex.com/Thread/View.aspx?ThreadId=230051
Does unity just make clasess with out needing anything registered?
Additionally, if you are eager to get more detail into how Unity can do this, simple download Unity 2.0 and open the source code that is provided with the installer.
I hope this helps.
Thanks,
Damian
You do not need to register a type you want to resolve. You need to register the dependencies of a type, that you want to resolve. In this case, the Shell doesn't need any dependencies, so you can resolve it simply. But for an example (not really), if your shell getting an interface IService as a parameter, then you must register IService, before you resolve Shell.
Otherwise you will get Dependency Resolution Failed Exception. In Prism 4.1 it will be swallowed silently due to TryResolve.

Handling dependencies with IoC that change within a single function call

We are trying to figure out how to setup Dependency Injection for situations where service classes can have different dependencies based on how they are used. In our specific case, we have a web app where 95% of the time the connection string is the same for the entire Request (this is a web application), but sometimes it can change.
For example, we might have 2 classes with the following dependencies (simplified version - service actually has 4 dependencies):
public LoginService (IUserRepository userRep)
{
}
public UserRepository (IContext dbContext)
{
}
In our IoC container, most of our dependencies are auto-wired except the Context for which I have something like this (not actual code, it's from memory ... this is StructureMap):
x.ForRequestedType().Use()
.WithCtorArg("connectionString").EqualTo(Session["ConnString"]);
For 95% of our web application, this works perfectly. However, we have some admin-type functions that must operate across thousands of databases (one per client). Basically, we'd want to do this:
public CreateUserList(IList<string> connStrings)
{
foreach (connString in connStrings)
{
//first create dependency graph using new connection string
????
//then call service method on new database
_loginService.GetReportDataForAllUsers();
}
}
My question is: How do we create that new dependency graph for each time through the loop, while maintaining something that can easily be tested?
To defer the creation of an object until runtime, you can use a factory:
public interface ILoginServiceFactory
{
ILoginService CreateLoginService(string connectionString);
}
Usage:
public void CreateUserList(IList<string> connStrings)
{
foreach(connString in connStrings)
{
var loginService = _loginServiceFactory.CreateLoginService(connString);
loginService.GetReportDataForAllUsers();
}
}
Within the loop, do:
container.With("connectionString").EqualTo(connString).GetInstance<ILoginService>()
where "connectionString" is the name of a string constructor parameter on the concrete implementation of ILoginService.
So most UserRepository methods use a single connection string obtained from session, but several methods need to operate against a list of connection strings?
You can solve this problem by promoting the connection string dependency from IContext to the repository and adding two additional dependencies - a context factory and a list of all the possible connections strings the repository might need to do its work:
public UserRepository(IContextFactory contextFactory,
string defaultConnectionString,
List<string> allConnectionStrings)
Then each of its methods can build as many IContext instances as they need:
// In UserRepository
public CreateUserList() {
foreach (string connString in allConnectionStrings) {
IContext context = contextFactory.CreateInstance(connString);
// Build the rest of the dependency graph, etc.
_loginService.GetReportDataForAllUsers();
}
}
public LoginUser() {
IContext context = contextFactory.CreateInstance(defaultConnectionString);
// Build the rest of the dependency graph, etc.
}
We ended up just creating a concrete context and injecting that, then changing creating a wrapper class that changed the context's connection string. Seemed to work fine.

Why getting a 202 in two equal setup structuremap code paths

In the C# language, using StructureMap 2.5.4, targeting .NET Framework 3.5 libraries.
I've taken the step to support multiple Profiles in a structure map DI setup, using ServiceLocator model with Bootstrapper activation. First setup was loading default registry, using the scanner.
Now I like to determine runtime what Registry configuration I like to use. Scanning and loading multiple assemblies with registries.
Seems it's not working for the actual implementation (Getting the 202, default instance not found), but a stripped test version does work. The following setup.
Two assemblies containing Registries and implementations
Scanning them in running AppDomain, providing the shared Interface, and requesting Creation Of Instance, using the interfaces in constructor (which get dealt with thanx to the profile on Invokation)
Working code sample below (same structure for other setup, but with more complex stuff, that get's a 202):
What type of couses are possible for a 202, specifically naming the System.Uri type, not being handles by a default type?? (uri makes no sense)
// let structure map create instance of class tester, that provides the registered
// interfaces in the registries to the constructor of tester.
public class Tester<TPOCO>
{
private ITestMe<TPOCO> _tester;
public Tester(ITestMe<TPOCO> some)
{
_tester = some;
}
public string Exec()
{
return _tester.Execute();
}
}
public static class Main {
public void ExecuteDIFunction() {
ObjectFactory.GetInstance<Tester<string>>().Exec();
}
}
public class ImplementedTestMe<TSome> : ITestMe<TSome>
{
public string Execute()
{
return "Special Execution";
}
}
public class RegistryForSpecial : Registry
{
public RegistryForSpecial()
{
CreateProfile("Special",
gc =>
{
gc.For(typeof(ITestMe<>)).UseConcreteType(typeof(ImplementedTestMe<>));
});
}
}
Background articles on Profiles I used.
How to setup named instances using StructureMap profiles?
http://devlicio.us/blogs/derik_whittaker/archive/2009/01/07/setting-up-profiles-in-structuremap-2-5.aspx
http://structuremap.sourceforge.net/RegistryDSL.htm
EDIT:
It seemed the missing interface was actually the one being determined runtime. So here is the next challange (and solved):
I provided a default object whenever StructureMap needs to create the object. Like:
x.ForRequestedType<IConnectionContext>()
.TheDefault.Is.Object(new WebServiceConnection());
This way I got rid of the 202 error, because now a real instance could be used whever structure map needed the type.
Next was the override on runtime. That did not work out at first using the ObjectFactory.Configure method. Instead I used the ObjectFactory.Inject method to overide the default instance. Works like a charm.
ObjectFactory.Inject(typeof(IConnectionContext), context);
Loving the community effort.
Error code 202 means a default instance could not be built for the requested type. Your test code is apparently not equal to your real code that fails. If you are getting an error about Uri, you likely have a dependency that requires a Uri in its constructor. It may not be the class you are asking for - it may be one of that classes dependendencies - or one of the dependencies dependencies... somewhere down the line someone is asking StructureMap to resolve a Uri, which it cannot do, without some help from you.

Resources