StructureMap Error 202 Setting up IOC container - c#

I'm getting an error:
StructureMap Exception Code: 202
No Default Instance defined for PluginFamily MVCPoco.Services.IService, MVCPoco.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Line 96: {
Line 97: Type controllerType = base.GetControllerType(context, controllerName);
Line 98: return ObjectFactory.GetInstance(controllerType) as IController;
Line 99: }
Line 100: }
the error occurs in line 98
Any ideas?
I'm using asp.net mvc 2 preview 2 that ships with visual studio 2010.

The controller you are trying to instantiate has a constructor dependency on IService. You have to make sure that you register a concrete implementation of IService when you configure StructureMap.
The DefaultConventionScanner will only register implementations that have the same name as their interface (without the leading I). So, unless your implementation of IService is named Service, it will not be registered automatically. To register it explicitly, add something like this to your inititalization script:
x.For<IService>().Use<MyService>();
Alternatively, if you are running StructureMap from the latest source code, you can make use of the SingleImplementationScanner in your Scan() expression:
y.With(new SingleImplementationScanner());
and that will automatically register concrete types if they are the only implementation of an interface in the scanned code, regardless of name.

You must register the types to be injected at application start within the ObjectFactory.Configure function. Check out the documents over on Structure Map's site for Configuring your IOC Container.
Andrew

Well, i've set up correctly the structuremap i've just switched to the method
public static void Configure()
{
ObjectFactory.Initialize(x =>
x.AddRegistry(new IOCRegistry())); // in here i have registered my dependencies with for method.
}

Related

How to mock autofac type registration?

I have following registration in my autofac container:
builder.RegisterType<EmailService>().As<IEmailService>().InstancePerLifetimeScope();
builder.RegisterType<AzureBlobStorageService>().InstancePerLifetimeScope();
Some commands depend on these services. But in my tests I don't need them, it's not what I want to test.
So I tried to rewrite registrations in following way:
builder.RegisterType<Mock<EmailService>>().As<IEmailService>().InstancePerLifetimeScope();
builder.RegisterType<Mock<AzureBlobStorageService>>().InstancePerLifetimeScope();
But I'm getting error:
Message: System.ArgumentException : The type 'Moq.Mock 1[EmailService]' is not assignable to service 'Moq.Mock`1[[IEmailService, ...]]'.
How to do it proper way?
If you want to register a mock for the IEmailService interface, you could use the RegisterInstance method:
builder.RegisterInstance(new Mock<IEmailService>().Object)
.As<IEmailService>();

How to add IEndpointsOperations interface using dependency injection in .net core 2.2

I want to use LoadContentAsync method from IEndpointOperations interface with dependency injection available in .net core 2.2. Please share some code samples. I tried to add AddSingleton/AddTransient in Startup.cs and tried to use it in the controller constructor. But i get below error,
Unhandled Exception: System.ArgumentException: Cannot instantiate
implementation type
'Microsoft.Azure.Management.Cdn.IEndpointsOperations' for service type
'Microsoft.Azure.Management.Cdn.IEndpointsOperations'.
Exact method to be consumed is in below link,
https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.management.cdn.endpointsoperationsextensions.loadcontentasync?view=azure-dotnet#Microsoft_Azure_Management_Cdn_EndpointsOperationsExtensions_LoadContentAsync_Microsoft_Azure_Management_Cdn_IEndpointsOperations_System_String_System_String_System_String_System_Collections_Generic_IList_System_String__System_Threading_CancellationToken_
You need to let the system know the implementation class of an interface in the startup class. For example:
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddSingleton<IClass1, Class1>();
}
May I know the implementation class of the interface IEndpointsOperations?

Unity DI, design-time configuration in layered application

We have been using Unity container for dependency injection without any problems for a couple of years. Simplified we have three layers Web/Domain/Data.
We use design-time configuration to be able to switch some implementations for different builds.
IMyDataInterface is registered from web.config. Data-layer resolves IMyDataInterface successfully. When trying to resolve IMyDataInterface from Domain-layer it fails with the following message.
InvalidOperationException - The current type, IMyDataInterface, is an interface and cannot be constructed. Are you missing a type mapping?
Each layer has a UnityConfig-class that registers the dependencies.
Web creates IUnityContainer instance A
Calls Web.UnityConfig.RegisterTypes(A)
Registers design-time types from web.config by running A.LoadConfiguration()
(web.config contains registration of IMyDataInterface)
Registers types from Web-layer
Calls Domain.UnityConfig.RegisterTypes(A)
Registers types from Domain-layer
Calls Data.UnityConfig.RegisterTypes(A)
Registers types from Data-layer
public class MyDataClass
{
public MyDataClass(IMyDataInterface dependency)
{
// dependency is resolved
}
}
public class MyDomainClass
{
public MyDomainClass(IMyDataInterface dependency)
{
// dependency FAILS to resolve
}
}
If I register type IMyDataInterface in Data.UnityConfig, everything works but I need to be able to switch implementation at design-time using web.config.

SimpleInjector MvcSitemapProvider

I'm using
VS2013 MVC5,
SimpleInjector 2.4.1
MvcSiteMapProvider.MVC5.DI.SimpleInjector.Modules 4.4.10
and I'm getting the following error when calling 'Verify' on the container
Additional information: The configuration is invalid. Creating the instance for type IAttributeAssemblyProvider failed. The registered delegate for type IAttributeAssemblyProvider threw an exception. The constructor of the type AttributeAssemblyProvider contains the parameter of type IEnumerable<String> with name 'includeAssemblies' that is not registered. Please ensure IEnumerable<String> is registered in the container, or change the constructor of AttributeAssemblyProvider.
The array it is referencing is :
string[] includeAssembliesForScan = new string[] { "MyProject" };
and this is what seems to be the culprit :
container.RegisterSingle<ReflectionSiteMapNodeProvider>(() =>
container.GetInstance<ReflectionSiteMapNodeProviderFactory>()
.Create(includeAssembliesForScan));
The signature for the create method is :
public MvcSiteMapProvider.Builder.ReflectionSiteMapNodeProvider Create(System.Collections.Generic.IEnumerable<string> includeAssemblies)
Member of MvcSiteMapProvider.Builder.ReflectionSiteMapNodeProviderFactory
I think the IAttributeAssemblyProvider is being registered as per below
// Single implementations of interface with matching name (minus the "I").
CommonConventions.RegisterDefaultConventions(
(interfaceType, implementationType) => container.RegisterSingle(interfaceType, implementationType),
new Assembly[] { siteMapProviderAssembly },
allAssemblies,
excludeTypes,
string.Empty);
since :
public class AttributeAssemblyProvider : IAttributeAssemblyProvider
and the ctor is :
public AttributeAssemblyProvider(
IEnumerable<string> includeAssemblies,
IEnumerable<string> excludeAssemblies)
{...}
Thanks in advance for any help
stack trace is :
at SimpleInjector.InstanceProducer.VerifyExpressionBuilding() at
SimpleInjector.Container.VerifyIfAllExpressionsCanBeBuilt(InstanceProducer[]
producersToVerify) at
SimpleInjector.Container.VerifyIfAllExpressionsCanBeBuilt() at
SimpleInjector.Container.Verify() at
MyProject.App_Start.SimpleInjectorInitializer.Intialise() in
\App_Start\SimpleInjectorInitializer.cs:line 54 at
MyProject.MvcApplication.Application_Start() in \Global.asax.cs:line
16
The latest versions of the external DI config files don't automatically update when you upgrade if you have changed them. Be sure you have merged in the latest versions of CommonConventions.cs and MvcSiteMapProviderContainerInitializer.cs from the master branch (this is to be done manually, but it helps a lot if you use a diff tool to quickly see the changes). You can also view the releases list to see the various points where updates were done to the DI configuration with direct links to the diff on GitHub.
The latest version of CommonConventions.RegisterDefaultConventions excludes auto-registration of any types that have a string parameter in the constructor (which AttributeAssemblyProvider does), so be sure you have merged the latest changes of that file into your project.
Of course, if all else fails you can add typeof(AttributeAssemblyProvider) to the excludeTypes array and it will no longer be auto-registered. It is not supposed to be because it has a factory class that instantiates it named AttributeAssemblyProviderFactory.
Also, if you are not using MvcSiteMapNodeAttribute to register nodes, it is not necessary to have it in your configuration at all. Removing it will make your SiteMap load a little faster.
To remove it, change this...
container.RegisterSingle<ReflectionSiteMapNodeProvider>(() => container.GetInstance<ReflectionSiteMapNodeProviderFactory>()
.Create(includeAssembliesForScan));
// Register the sitemap builders
container.RegisterSingle<ISiteMapBuilder>(() => container.GetInstance<SiteMapBuilderFactory>()
.Create(new CompositeSiteMapNodeProvider(container.GetInstance<XmlSiteMapNodeProvider>(), container.GetInstance<ReflectionSiteMapNodeProvider>())));
To this...
// Register the sitemap builders
container.RegisterSingle<ISiteMapBuilder>(() => container.GetInstance<SiteMapBuilderFactory>()
.Create(container.GetInstance<XmlSiteMapNodeProvider>()));
This is exactly what the "MvcSiteMapProvider_ScanAssembliesForSiteMapNodes" web.config setting does when set to "false" when you are using the internal DI container.

IValidator could not be located with the ServiceLocator

I get the following error when using sharparchitecture and try to call IValidatable.IsValid on a Domain Object.
How can I register an instance of the NHibernate validator against the common service locator?
I have seen the following unit tests:
http://code.google.com/p/sharp-architecture/source/browse/trunk/src/SharpArch/SharpArch.Tests/SharpArch.Core/SafeServiceLocatorTests.cs?spec=svn385&r=385
Any help with this would really be appreciated.
The needed dependency of type IValidator could not be located with the ServiceLocator. You'll need to register it with the Common Service Locator (CSL) via your IoC's CSL adapter.
at SharpArch.Core.SafeServiceLocator`1.GetService() in C:\MyStuff\Projects\SharpArchGitHub\src\SharpArch\SharpArch.Core\SafeServiceLocator.cs:line 29
at SharpArch.Core.DomainModel.ValidatableObject.IsValid() in C:\MyStuff\Projects\SharpArchGitHub\src\SharpArch\SharpArch.Core\DomainModel\ValidatableObject .cs:line 11
at Tuhdoo.Common.Validation.ValidatableExtensions.Validate(IValidatable entity) in D:\Repository\Tuhdoo\src\Tuhdoo.Common\Validation\ValidatableExtensions.cs:line 26
This turned out to be pretty obvious I had a slap head moment when I realised I hadn't registered the IValidator with my DI Conatiner.

Categories