Closed gswartz777 closed 2 years ago
What does your Program.cs
look like, do you have the appropriate .UseLamar()
as shown here: https://jasperfx.github.io/lamar/documentation/ioc/aspnetcore/
Ah thanks. Yeah I missed the program update. Got that updated but after doing that it's not resolving one of the services that should be injected into my controller. It's complaining about not being able to resolve the IInterceptor class defined in another project in the solution, so it's not in the same assembly. Guess I'm not clear on how to do that. From reading here - https://jasperfx.github.io/lamar/documentation/ioc/registration/auto-registration-and-conventions/ - I thought I had to specify the assembly name in s.Assembly("Net5Test2.BLL") Guess it must be something else?
using Lamar;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Net5Test2.BLL;
namespace Net5Test2
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureContainer(ServiceRegistry services)
{
services.AddMvc();
services.AddLogging();
services.Scan(s =>
{
s.Assembly("Net5Test2.BLL");
s.TheCallingAssembly();
s.WithDefaultConventions();
});
services.AddScoped<IDbClass, DbClass>();
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
}
// 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("/Home/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.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
"default",
"{controller=Home}/{action=Index}/{id?}");
});
}
}
}
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Net5Test2.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Net5Test2.BLL;
namespace Net5Test2.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IInterceptor _interceptor;
public HomeController(ILogger<HomeController> logger, IInterceptor interceptor)
{
_logger = logger;
_interceptor = interceptor;
}
public IActionResult Index()
{
_interceptor.Save();
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
And in another project I have the following.
using System;
namespace Net5Test2.BLL
{
public interface IInterceptor
{
void Save();
}
public class MyInterceptor : IInterceptor
{
private readonly IDbClass _dbClass;
public MyInterceptor(IDbClass dbClass)
{
_dbClass = dbClass;
}
public void Save()
{
_dbClass.Save();
}
}
public interface IDbClass
{
void Save();
}
public class DbClass : IDbClass
{
public void Save()
{
}
}
}
Just a off the top of my head guess, but this is probably the culprit (typo):
s.Assembly("Net5Test2.BLL");
Don't think so. Double checked it, copied what you had and still doesn't work. I pushed it to my gitlab repo if you want to take a look - https://gitlab.com/gswartz/net5test2
Oh, I thought the "B" in .BLL
was a typo for .DLL
. 😄 Try using the .WhatDoIHave()
and .WhatDidIScan()
diagnostics, maybe those will give you a clue. See: https://jasperfx.github.io/lamar/documentation/ioc/diagnostics/
FYI, you can get to those methods by casting the app.ApplicationServices
to IContainer
. I usually do this in the Startup.Configure
method like so:
if(IsDebugMode)
{
var container = (IContainer)app.ApplicationServices;
Log.Logger.Verbose(container.WhatDidIScan());
Log.Logger.Verbose(container.WhatDoIHave());
}
WhatDidIScan seemed to come up with the right assembly.
Assemblies
----------
* Net5Test2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
* Net5Test2.BLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Conventions
--------
* Default I[Name]/[Name] registration convention
No problems were encountered in exporting types from Assemblies
However I don't see the IInterceptor in the WhatDoIHave log. I'm assuming I should?
I would expect that you should, do you see all the other registrations from that assembly?
Also, try rearranging the scan method a little, I can remember if this would make a difference or not, but it's worth a shot:
services.Scan(s =>
{
s.WithDefaultConventions();
s.Assembly("Net5Test2.BLL");
s.TheCallingAssembly();
});
If that doesn't help, then I'm out of ideas. Everything else you have going on looks correct to me.
I can add additional interfaces and classes to the referenced project and everything loads fine. The only one it doesn't seem to find is the MyInterceptor class and interface. I'm wondering if the word interceptor is causing some problem. If I rename it it picks it up just fine. Very odd.
i'd say to move services.AddControllersWithViews();
into public void ConfigureContainer(ServiceRegistry services)
tack on .AddControllersAsServices()
to the end of AddControllersWithViews
so mvc knows to build controllers from the DI (it seams weird to me that this isn't the default)
next your MyInterceptor doesn't follow the default convention. either
s.SingleImplementationsOfInterface();
or s.RegisterConcreteTypesAgainstTheFirstInterface();
next, maybe preference here but i prefer selecting assemblies from a known type.
s.AssemblyContianingType<IDbClass>();
or w/e you think is the best entry type to that project/dll
I just installed .net5 and created a new .net core app to do some learning. In trying to get structuremap set up for it I came across Lamar. Installed that with the nuget package manager and tried to follow along with this - https://jasperfx.github.io/lamar/documentation/ioc/aspnetcore/
When I run the code I get the error "Unable to cast object of type 'Microsoft.Extensions.DependencyInjection.ServiceCollection' to type 'Lamar.ServiceRegistry" Here's my startup class.