Created
November 17, 2020 18:07
-
-
Save gitcob/9a4092d583947d622efb4a70a262ea48 to your computer and use it in GitHub Desktop.
Blazor Server App with Simple Injector issue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using System.Reflection; | |
using Microsoft.AspNetCore.Components; | |
using SimpleInjector.Advanced; | |
namespace BlazorApp1 | |
{ | |
public sealed class InjectPropertySelectionBehavior : IPropertySelectionBehavior | |
{ | |
public bool SelectProperty(Type implementationType, PropertyInfo prop) => | |
prop.GetCustomAttributes(typeof(InjectAttribute)).Any(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fail: Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost[111] | |
Unhandled exception in circuit 'KC8Jj8keAWjOJN4IdmgP_cjWj3iSP7k1eoY5T10DzcU'. | |
System.InvalidOperationException: Cannot provide a value for property 'ForecastService' on type 'BlazorApp1.Pages.FetchData'. There is no registered service of type 'BlazorApp1.Data.WeatherForecastService'. | |
at Microsoft.AspNetCore.Components.ComponentFactory.<>c__DisplayClass6_0.<CreateInitializer>g__Initialize|2(IServiceProvider serviceProvider, IComponent component) | |
at Microsoft.AspNetCore.Components.ComponentFactory.PerformPropertyInjection(IServiceProvider serviceProvider, IComponent instance) | |
at Microsoft.AspNetCore.Components.ComponentFactory.InstantiateComponent(IServiceProvider serviceProvider, Type componentType) | |
at Microsoft.AspNetCore.Components.RenderTree.Renderer.InstantiateChildComponentOnFrame(RenderTreeFrame& frame, Int32 parentComponentId) | |
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewComponentFrame(DiffContext& diffContext, Int32 frameIndex) | |
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewSubtree(DiffContext& diffContext, Int32 frameIndex) | |
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InsertNewFrame(DiffContext& diffContext, Int32 newFrameIndex) | |
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForFramesWithSameSequence(DiffContext& diffContext, Int32 oldFrameIndex, Int32 newFrameIndex) | |
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl) | |
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForFramesWithSameSequence(DiffContext& diffContext, Int32 oldFrameIndex, Int32 newFrameIndex) | |
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl) | |
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForFramesWithSameSequence(DiffContext& diffContext, Int32 oldFrameIndex, Int32 newFrameIndex) | |
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl) | |
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForFramesWithSameSequence(DiffContext& diffContext, Int32 oldFrameIndex, Int32 newFrameIndex) | |
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl) | |
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForFramesWithSameSequence(DiffContext& diffContext, Int32 oldFrameIndex, Int32 newFrameIndex) | |
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl) | |
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.ComputeDiff(Renderer renderer, RenderBatchBuilder batchBuilder, Int32 componentId, ArrayRange`1 oldTree, ArrayRange`1 newTree) | |
at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment) | |
at Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderInExistingBatch(RenderQueueEntry renderQueueEntry) at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Reflection; | |
using Microsoft.AspNetCore.Components; | |
using SimpleInjector; | |
namespace BlazorApp1 | |
{ | |
public sealed class SimpleInjectorComponentActivator : IComponentActivator | |
{ | |
private readonly Dictionary<Type, InstanceProducer<IComponent>> _applicationProducers; | |
public SimpleInjectorComponentActivator(Container container, Assembly[] assemblies) | |
{ | |
_applicationProducers = ( | |
from type in container.GetTypesToRegister<IComponent>(assemblies) | |
let producer = Lifestyle.Transient.CreateProducer<IComponent>(type, container) | |
select (type, producer)) | |
.ToDictionary(v => v.type, v => v.producer); | |
} | |
public IComponent CreateInstance(Type type) => | |
_applicationProducers.TryGetValue(type, out var producer) | |
? producer.GetInstance() | |
: DefaultCreateInstance(type); | |
private static IComponent DefaultCreateInstance(Type componentType) | |
{ | |
var instance = Activator.CreateInstance(componentType); | |
if (!(instance is IComponent component)) | |
{ | |
throw new ArgumentException($"The type {componentType.FullName} does not implement {nameof(IComponent)}.", nameof(componentType)); | |
} | |
return component; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using BlazorApp1.Data; | |
using Microsoft.AspNetCore.Builder; | |
using Microsoft.AspNetCore.Components; | |
using Microsoft.AspNetCore.Hosting; | |
using Microsoft.Extensions.Configuration; | |
using Microsoft.Extensions.DependencyInjection; | |
using Microsoft.Extensions.Hosting; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Reflection; | |
using SimpleInjector; | |
using SimpleInjector.Advanced; | |
using SimpleInjector.Lifestyles; | |
namespace BlazorApp1 | |
{ | |
public sealed class InjectPropertySelectionBehavior : IPropertySelectionBehavior | |
{ | |
public bool SelectProperty(Type implementationType, PropertyInfo prop) => | |
prop.GetCustomAttributes(typeof(InjectAttribute)).Any(); | |
} | |
public sealed class SimpleInjectorComponentActivator : IComponentActivator | |
{ | |
private readonly Dictionary<Type, InstanceProducer<IComponent>> _applicationProducers; | |
public SimpleInjectorComponentActivator(Container container, Assembly[] assemblies) | |
{ | |
_applicationProducers = ( | |
from type in container.GetTypesToRegister<IComponent>(assemblies) | |
let producer = Lifestyle.Transient.CreateProducer<IComponent>(type, container) | |
select (type, producer)) | |
.ToDictionary(v => v.type, v => v.producer); | |
} | |
public IComponent CreateInstance(Type type) => | |
_applicationProducers.TryGetValue(type, out var producer) | |
? producer.GetInstance() | |
: DefaultCreateInstance(type); | |
private static IComponent DefaultCreateInstance(Type componentType) | |
{ | |
var instance = Activator.CreateInstance(componentType); | |
if (!(instance is IComponent component)) | |
{ | |
throw new ArgumentException($"The type {componentType.FullName} does not implement {nameof(IComponent)}.", nameof(componentType)); | |
} | |
return component; | |
} | |
} | |
public class Startup | |
{ | |
private readonly Container _container; | |
public Startup(IConfiguration configuration) | |
{ | |
Configuration = configuration; | |
_container = new Container | |
{ | |
Options = | |
{ | |
DefaultScopedLifestyle = new AsyncScopedLifestyle(), | |
ResolveUnregisteredConcreteTypes = true, | |
UseStrictLifestyleMismatchBehavior = true, | |
PropertySelectionBehavior = new InjectPropertySelectionBehavior() | |
} | |
}; | |
} | |
public IConfiguration Configuration { get; } | |
// This method gets called by the runtime. Use this method to add services to the container. | |
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 | |
public void ConfigureServices(IServiceCollection services) | |
{ | |
services.AddRazorPages(); | |
services.AddServerSideBlazor(); | |
// services.AddSingleton<WeatherForecastService>(); <- Template uses the built-in DI to register the service | |
// Sets up the basic configuration that for integrating Simple Injector with | |
// ASP.NET Core by setting the DefaultScopedLifestyle, and setting up auto | |
// cross wiring. | |
services.AddSimpleInjector(_container, options => | |
{ | |
// AddAspNetCore() wraps web requests in a Simple Injector scope and | |
// allows request-scoped framework services to be resolved. | |
options.AddAspNetCore(ServiceScopeReuseBehavior.OnePerRequest) | |
// Ensure activation of a specific framework type to be created by | |
// Simple Injector instead of the built-in configuration system. | |
// All calls are optional. You can enable what you need. For instance, | |
// ViewComponents, PageModels, and TagHelpers are not needed when you | |
// build a Web API. | |
.AddControllerActivation() | |
.AddViewComponentActivation() | |
.AddPageModelActivation() | |
.AddTagHelperActivation(); | |
}); | |
var autoRegistrationAssemblies = new[] { typeof(Startup).Assembly }; | |
services.AddSingleton<IComponentActivator>( | |
new SimpleInjectorComponentActivator(_container, autoRegistrationAssemblies)); | |
_container.Register<WeatherForecastService>(); // <- Registration moved here | |
} | |
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | |
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) | |
{ | |
if (env.IsDevelopment()) | |
{ | |
app.UseDeveloperExceptionPage(); | |
} | |
else | |
{ | |
app.UseExceptionHandler("/Error"); | |
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. | |
app.UseHsts(); | |
} | |
app.UseHttpsRedirection(); | |
app.UseStaticFiles(); | |
app.UseRouting(); | |
app.UseEndpoints(endpoints => | |
{ | |
endpoints.MapBlazorHub(); | |
endpoints.MapFallbackToPage("/_Host"); | |
}); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment