-
Notifications
You must be signed in to change notification settings - Fork 458
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ASP.NET Core facility #376
Conversation
Push-AppveyorArtifact $env:APPVEYOR_BUILD_FOLDER\src\Castle.Windsor.Tests\$testBinPath\TestResult_Windsor.xml | ||
|
||
Push-AppveyorArtifact $env:APPVEYOR_BUILD_FOLDER\src\Castle.Facilities.WcfIntegration.Tests\$testBinPath\TestResult_WcfIntegration.xml | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This really was not adding much value because the log output is enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was also causing pathing issues. Bad reason for a build to fail in appveyor but pass locally :'(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed that NUnit's console output is much better for failures now so we don't need the last 2, however the "/api/testresults/nunit/..." ones are for the "Tests" tab in AppVeyor. Castle Core only has the first ones.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does anyone look at those test tabs? I dont. Also noticed test output from netcoreapp1.0 would wipe out test results from net45 because of the namespace collisions. Let me know if you use this and I will put it back.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, the test tab is pretty pointless because I don't think you can ever navigate to anything including failures unlikely TeamCity.
It doesn't look like one test run wipes out the other, there are duplicate test names under different file names, Castle.Windsor.Tests.dll
(.NET 4.5) and Castle.Windsor.Tests.exe
(.NET Core).
But yer I agree let's just get rid of them. Should we also run NUnit's runner with --noresult
since the command line output is plenty good?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var handlers = container.Kernel.GetHandlers(); | ||
var hasAspNetCoreFrameworkRegistrations = handlers.Any(x => x.ComponentModel.Implementation.FullName.StartsWith("Microsoft.AspNetCore")); | ||
if (hasAspNetCoreFrameworkRegistrations) | ||
throw new Exception("Looks like you have implementations registered from 'Microsoft.AspNetCore'. Please do not do this as it could lead to torn lifestyles. Please remove the registrations."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should probably rename the exception message to:
Looks like you have implementations registered from 'Microsoft.AspNetCore'. Please do not do this as it could lead to torn lifestyles. Please remove the registrations from Castle Windsor.
@jonorossi - If you could take a look that would be great. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Fir3pho3nixx looking good, just a bunch of review comments, some you might have already thought about.
|
||
private static void ThrowIfFrameworkComponentsAreRegistered(IWindsorContainer container) | ||
{ | ||
var offendingFrameworkTypes = InvalidFrameworkConfigurationNamespaces; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable name refers to type names which you prime with namespace names than compare against Type.FullName
, obviously FullName
returns the namespace but if this should only match the namespace then it should probably look at namespace otherwise should be renamed.
I wouldn't have a problem with this being hardcoded compared against a single string rather than "building for the future".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable name refers to type names which you prime with namespace names than compare against Type.FullName, obviously FullName returns the namespace but if this should only match the namespace then it should probably look at namespace otherwise should be renamed.
Will do the namespace option.
I wouldn't have a problem with this being hardcoded compared against a single string rather than "building for the future".
Will move it back to how I had it before. :D
var offendingFrameworkTypes = InvalidFrameworkConfigurationNamespaces; | ||
foreach (var invalidFrameworkConfiguredType in offendingFrameworkTypes) | ||
{ | ||
var handlers = container.Kernel.GetHandlers(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should only fetch the handlers once outside the loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, that is garbage code. Will fix.
var handlers = container.Kernel.GetHandlers(); | ||
var hasAspNetCoreFrameworkRegistrations = handlers.Any(x => x.ComponentModel.Implementation.FullName.StartsWith(invalidFrameworkConfiguredType)); | ||
if (hasAspNetCoreFrameworkRegistrations) | ||
throw new Exception($"Looks like you have implementations registered from '{string.Join(",",InvalidFrameworkConfigurationNamespaces)}'. Please do not do this as it could lead to torn lifestyles and captive dependencies. Please remove the registrations from Castle.Windsor."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line should have surrounding braces, and probably should be broken up on multiple lines rather than 300 or so characters.
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.5" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it now Microsoft's recommendation to reference Microsoft.AspNetCore.All
? I would have thought since we are a library we'd want to take a smaller dependency?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can cut this right back.
I just thought it would be handy if you created a console app, then installed Castle.Factilities.AspNetCore you would have everything ready go as a reference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think we should cut it back.
The ASP.NET team just announced today that they are actually introducing a new Microsoft.AspNetCore.App
package and are changing their new project templates not to use ".All" in favour of this one because the "All" metapackage actually brings in heaps of stuff that isn't expected like Azure KeyVault, a Redis client and Sqlite. We really shouldn't force others to bring in packages we don't need for convenience.
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netcoreapp2.0</TargetFramework> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I vaguely remember something different about netcoreapp2.0 and ASP.NET Core 2 projects, but just wanting to confirm this doesn't block our facility library from being used by another library.
public static void UseCastleWindsorMiddleware<T>(this IApplicationBuilder app, IWindsorContainer container) where T : class, ICastleWindsorMiddleware | ||
{ | ||
container.Register(Component.For<T>()); | ||
app.Use(async (context, next) => { await container.Resolve<T>().Invoke(context, next); }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does calling Invoke
directly here rather than returning the middleware cause any problems with the framework? I'm an ASP.NET Core newbie but I just wondered if there was maybe a diagnostic trace that it keeps state of as each middleware is executed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does calling Invoke directly here rather than returning the middleware cause any problems with the framework?
Not that I have come across. Do you have any further links?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, it was just a thought as I've never dug into how this stuff works.
|
||
using Microsoft.AspNetCore.Http; | ||
|
||
public interface ICastleWindsorMiddleware |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you explain why this couldn't use IMiddleware
? Does ASP.NET Core automatically wire up IMiddleware
s not allowing them to be resolved from the container?
It looks like ASP.NET Core already handles this, see the "Per-request dependencies" section, is this functionality useful?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you explain why this couldn't use IMiddleware? Does ASP.NET Core automatically wire up IMiddlewares not allowing them to be resolved from the container?
Great question. You can definitely do this but you are moving away from the Windsor container and falling back onto "Framework Configured Container". This creates problems if your middleware consumes dependencies that are known to Windsor but not registered within the IServiceCollection. If anyone decided to go down this route they will end up with a mish mash of registrations across both containers. This should be avoided at all costs.
It looks like ASP.NET Core already handles this, see the "Per-request dependencies" section, is this functionality useful?
If their middleware does not consume any dependencies, then this functionality is useful. Otherwise it is recommended you use our extension because then you are free to consume your own types(registered in Windsor) and framework types which is dealt with in the sub resolvers.
I did update the XML documentation for this extension.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still feels icky as it means your application code has to implement a container specific interface otherwise the container won't let you use it. It feels a bit like the lifestyle attributes Windsor has that aren't really recommended as registration/configuration should happen outside the application code, or the anti-pattern that is depending on IKernel
from non-factory components.
If a user did implement IMiddleware
or used someone else's middleware would ASP.NET Core automatically wire it up, or can we just tell them not to register it with ASP.NET Core and instead register it with the Windsor facility?
I think that the type name (Castle.Facilities.AspNetCore.ICastleWindsorMiddleware
) is something that keeps sticking its nose at me. Having the product name in the interface name is something I don't believe we've ever had to do before which sort of tells me we are doing something wrong, especially that Windsor doesn't have middleware but that this is a workaround.
I did update the XML documentation for this extension.
FYI, the interface doesn't have any documentation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still feels icky as it means your application code has to implement a container specific interface otherwise the container won't let you use it.
You are right it is superfluous and can be removed altogether.
If a user did implement IMiddleware or used someone else's middleware would ASP.NET Core automatically wire it up, or can we just tell them not to register it with ASP.NET Core and instead register it with the Windsor facility?
Not aware of anything that wires this up for you.
For framework middleware:
-
You still have to "tell" the IServiceCollection the middleware exists as a resolvable type.
-
You have to register the same type as middleware with the app builder.
-
It does not resolve types registered in Windsor, if you need this then register it in your container and use this extension method instead.
I think that the type name (Castle.Facilities.AspNetCore.ICastleWindsorMiddleware) is something that keeps sticking its nose at me.
Let's delete it. We still need the extension method though right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yay, ICastleWindsorMiddleware
is gone 🎉 .
Yes, we'll still need the extension method, you were saying trying to do it via the framework container will just cause too much pain so happy for it to stay, however I noticed you renamed the IApplicationBuilder
extension method:
app.UseCastleWindsorMiddleware<CustomMiddleware>(container);
... to ...
app.UseResolvableMiddleware<CustomMiddleware>(container);
I wonder if this new name is very clear, if you didn't want "Windsor" in the extension method name (which I thought was convention for these IApplicationBuilder thingys) then naming it just UseMiddleware
like the framework one would explain just as much but you'd have an overload with the container.
app.UseMiddleware<CustomMiddleware>(); // register with framework
app.UseMiddleware<CustomMiddleware>(container); // register with Windsor
Or maybe name it app.UseMiddlewareViaWindsor<CustomMiddleware>(container)
?
{ | ||
container.Register(Classes.FromAssemblyInThisApplication(typeof(TStartup).Assembly).BasedOn<Controller>().LifestyleScoped()); | ||
container.Register(Classes.FromAssemblyInThisApplication(typeof(TStartup).Assembly).BasedOn<ViewComponent>().LifestyleTransient()); | ||
container.Register(Classes.FromAssemblyInThisApplication(typeof(TStartup).Assembly).BasedOn<TagHelper>().LifestyleTransient()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If your controllers are in a different assembly do you want people register their components themselves and skip UseCastleWindsor
? You mentioned in the docs if they wanted different lifestyles but not if they are in different assemblies.
XML comments on these with what they specifically do would help people saving having to jump to the docs or into the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If your controllers are in a different assembly do you want people register their components themselves and skip UseCastleWindsor? You mentioned in the docs if they wanted different lifestyles but not if they are in different assemblies.
I updated the docs to be a bit clearer.
XML comments on these with what they specifically do would help people saving having to jump to the docs or into the code.
Also added some XML comments.
|
||
public static void AddCastleWindsor(this IServiceCollection services, IWindsorContainer container) | ||
{ | ||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see IHttpContextAccessor
used in the facility, just wanting to understand what it is needed for.
Push-AppveyorArtifact $env:APPVEYOR_BUILD_FOLDER\src\Castle.Windsor.Tests\$testBinPath\TestResult_Windsor.xml | ||
|
||
Push-AppveyorArtifact $env:APPVEYOR_BUILD_FOLDER\src\Castle.Facilities.WcfIntegration.Tests\$testBinPath\TestResult_WcfIntegration.xml | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed that NUnit's console output is much better for failures now so we don't need the last 2, however the "/api/testresults/nunit/..." ones are for the "Tests" tab in AppVeyor. Castle Core only has the first ones.
HI. Could it be interesting to add the Microsoft.Extensions.Logging as a resolver (or something) into the faciltiy? I know this would mean a dependancy on the Microsoft.Extensions.Logging but it is inbuilt and automatically registerd with aspnetcore. public class LoggerResolver : ISubDependencyResolver
{
private readonly ILoggerFactory _loggingFactory;
public LoggerResolver(ILoggerFactory loggingFactory)
{
_loggingFactory = loggingFactory;
}
public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model,
DependencyModel dependency)
{
return dependency.TargetType == typeof(ILogger);
}
public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model,
DependencyModel dependency)
{
return _loggingFactory.CreateLogger(model.Name);
}
} |
We are using the following meta NuGet package: <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.5" /> Had a quick look and this did include: <PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" /> In my original repo I also managed to inject LoggingFactory into a controller as a test. public HomeController(IUserService userService, ILoggerFactory loggerFactory, IViewBufferScope viewBufferScope)
{
this.userService = userService;
this.loggerFactory = loggerFactory;
this.viewBufferScope = viewBufferScope;
} Code is over here: https://github.com/fir3pho3nixx/Windsor.AspNetCore/blob/master/WebApp/Controllers/HomeController.cs#L15 You should be able to easily inject your framework types without having to register them in Windsor or using the sub dependency resolver. If this is not happening or not working I would love to see an example so I can fix it. |
@Fir3pho3nixx It is good to inject the factory, but even easiet to inject the ILogger directly. Hence, a good reason to add the resolver in your apnetcore Faciltiy. So you can allows inject a Microsoft.Extensions.Logging.ILogger out of the box. public HomeController(IUserService userService, ILogger logger, IViewBufferScope viewBufferScope)
{
this.userService = userService;
this.logger= logger;
this.viewBufferScope = viewBufferScope;
this.logger.LogDebug("Log something baby");
} Anyway, just an idea. Up to you.... Why inject the factory, with the resolver can inject the logger :-) |
@generik0 - Let me check this and get back to you. It should support ILogger. |
If i write: public HomeController(IUserService userService, ILoggerFactory loggerFactory, IViewBufferScope viewBufferScope)
{
this.userService = userService;
this.loggerFactory = loggerFactory;
this.viewBufferScope = viewBufferScope;
this.logger = this.loggingfactory.CreateLogger(this.GetType());
this.logger.LogDebug("Log something baby");
} Then i get a logger, you need to pass the caling type to the Factory to get the correct output in your log.. If you want to include this feature i can easily make pull request with the code. :-) Again, i would think it is usefull, and i would personly think it is good to have in the facility, and it fits with good SOLID and IoC practices to have the resolver in your factory :-) https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?tabs=aspnetcore2x |
Can you try again with the code here https://github.com/fir3pho3nixx/Windsor.AspNetCore. I have enabled the delegation of open/closed generics. This now allows constructors like this to be created with framework configured dependencies like: public HomeController(IUserService userService, ILoggerFactory loggerFactory, ILogger<HomeController> logger, IViewBufferScope viewBufferScope, IOpenGenericService<ClosedGenericTypeParameter> closedGenericService)
{
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
this.userService = userService ?? throw new ArgumentNullException(nameof(userService));
this.loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
this.viewBufferScope = viewBufferScope ?? throw new ArgumentNullException(nameof(viewBufferScope));
this.closedGenericService = closedGenericService;
} Following behaviours are supported:
Most of the change was here If there are any more glaring obvious things you can spot, by all means PR away to my forked remote branch. Thanks for helping us find this. Will commit this change with tests tomorrow night :) ** Edited ** Good catch! |
@fir3phonixx the resolver should do all the work for me. |
Yup, I could see how that could be irritating. I have added your resolver here: 0d46f46#diff-6e2e807723a1993c52dc81571e69c073 Thanks! |
I agree, |
@jonorossi - This is now ready for one final check. |
@jonorossi - I also double checked there were no undue memory leaks. I even introduced console and debug logging. I did find the fairness from the CPU/IO was a bit weird with netcore apps. I also introduced IDisposable on the AspNetUserService just to be sure burdens and scopes are behaving themselves. This was with the async ICastleWindsorMiddleware |
Should check this on ubuntu linux before merge. |
I guess that should be another pull request since Windsor doesn't have a Travis CI build like Castle Core. |
docs/facilities.md
Outdated
@@ -43,6 +43,7 @@ In addition to the above, as part of Castle Project, some other facilities are p | |||
* [System Web Facility](systemweb-facility.md) - Provides system web integration for web projects using `PerWebRequest` lifestyles. | |||
* [AspNet Mvc Facility](aspnetmvc-facility.md) - Provides aspnet mvc integration for web projects using Windsor. | |||
* [AspNet WebApi Facility](aspnetwebapi-facility.md) - Provides aspnet webapi integration for web projects using Windsor. | |||
* [AspNet Core Facility](aspnetcore-facility.md) - Provides aspnet core integration for web projects using Windsor. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"ASP.NET"
<PropertyGroup> | ||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> | ||
<PackageId>Castle.Facilities.AspNetCore</PackageId> | ||
<Title>Castle Windsor AspNet Core facility</Title> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"ASP.NET Core"
<ItemGroup> | ||
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.1" /> | ||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.2" /> | ||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor" Version="2.0.2" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm surprised this facility needs ASP.NET Core MVC and Razor, and not just the main ASP.NET Core package. I haven't had a chance to check out the work the Nancy guys have done to get Nancy running on ASP.NET Core but I thought this facility might be a drop in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Razor is there because of the activator for TagHelpers.
Mvc is there because of the activator for Controllers.
Open to any idea's that could make this easier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Open to any idea's that could make this easier.
I've got no ideas, I think just leave this as is for now. Nancy is different with its container usage anyway wired through the bootstrapper so let's get this going and the first person to want Windsor on Nancy can sort that one out.
CHANGELOG.md
Outdated
@@ -9,6 +9,7 @@ Breaking changes: | |||
- Created Castle.Facilities.AspNet.SystemWeb facility so we can remove this from the Windsor core library. (@fir3pho3nixx, #283) | |||
|
|||
New Features: | |||
- Created Castle.Facilities.AspNetCore facility to support Mvc web applications on dotnet core. (@fir3pho3nixx, #120) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you get a chance to try this out using ASP.NET Core on .NET Framework?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If not, feel free to just log an issue so we don't forget for v5 and defer it for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did check it for all of about 2-3 minutes before moving on to something else. Let me get back to you on this one. Let's hold out before raising the issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jonorossi - I looked at this again, it is definitely possible to run ASP.NET Core targeting net461.
The Visual Studio WebApp template appears to have a NuGet reference to Microsoft.AspNetCore.All which misleadingly targets netcoreapp2.0 instead of netstandard2.0. Once I added in the individual NuGets I needed it ran without any issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Visual Studio WebApp template appears to have a NuGet reference to Microsoft.AspNetCore.All which misleadingly targets netcoreapp2.0 instead of netstandard2.0. Once I added in the individual NuGets I needed it ran without any issues.
The Microsoft.AspNetCore.All
package by design is .NET Core only, I think also one of the reasons they have introduced Microsoft.AspNetCore.App
.
@Fir3pho3nixx sorry for sitting on your comments the last few days, I'll try to be more responsive. A few minor issues but that middleware interface is still a sticking point for me. We are nearly there 🤞. |
Don't worry.
Glad it is. I can delete the interface. Let me get those changes in tomorrow night and then we can evaluate what else we need then.
Time to squish me thinks. |
Yep. Let me know how .NET Framework goes. |
Hi I am using it on .Net Framework. I.e. MVC6 aspnet5 aka aspnetcore. I have copied the files over. |
@generik0 - The razor dependency is there for view components and tag helpers. Don’t think we can remove it if we want to support MVC. |
@Fir3pho3nixx I know why it is there. I am just thinking if we could do it differently. |
@generik0 - the castle windsor community has been waiting for so long for an aspnet core facility, I have personally been researching this problem for over a year now. Before we prematurely optimise this by applying separation of concerns perhaps we should make the entry easy breezy before we start breaking this out into different NuGet packages. I am not saying you are wrong, you are right. What I am saying is, let's keep it slim to start(which might mean breaking some SoC rules) and let the community decide as we go. What you are suggesting creates more documentation, more NuGet's and honestly this is not something I want for people out there as a first go. The templates for ASP.NET Core that come with VS2017 are rubbish, but that is where people start and unfortunately it includes references to meta NuGet packages like Microsoft.AspNet.Core.All. The barrier to entry should be kept low. We can evolve this later on. Not even Microsoft has solved this problem fully yet. Look forward to your response. |
I agree, we have been waiting a long time. So long I was forced to use autofac in a project :-: |
Hi. Should @Inject be working on the views? |
Yes it should! I will check this out before we release. Good catch! |
It is one of web college that has used it. |
Hi @Fir3pho3nixx |
Hi @Fir3pho3nixx Any ideas. I am at a loss... |
@generik0 - I will have a look. Give me 1/2 days I will get back to you. |
@Fir3pho3nixx Any luck? I have been trying to figure it out also. It gives no meaning when e.g. IHtmlLocalizer can be @Inject |
I need a bit more time on this one, there is no tidy way of achieving this. There no activators and classes in this area are all sealed. When I get back to London I will see if I can implement a custom razor feature that does this. |
ok, No problem Maybe we could do a xp session together and look into it if you like? |
Will have to wait until I get back to London. Currently in Japan. Will email you when I am back to set something up 👍 |
I have investigated this extensively over the weekend and came to the conclusion that the only way we can achieve this is by implementing a new "Razor Feature/Directive". I followed the path of how the existing inject directive works: Any extensibility like this is offered through the RazorViewEngineOptions: Unfortunately there is no interface for adding new Razor directives, there is also simply no public API for getting hold of the IRazorEngineBuilder either(which allows the adding of these features) when the IRazorEngine get's new'ed up. Specifically something like this: This kind of leaves in a place where we have to create a custom RazorViewEngine that emulates the existing features/directives of Microsoft plus the additional one for doing Castle Windsor compliant @Inject's. After raising this issue here: I also came to the conclusion that the tooling around this would lag behind and also produce errors when it really shouldn't. To make the @Inject work with the project in it's current form, you would have to cross wire your dependencies into the ServiceCollection. This is yukky and I would never recommend people go down this path. Here is also an issue I found with how SimpleInjector have approached this: I am interested to know how static service location would solve the problem, have you tried this? |
Hi. Great work!. Sorry it ended a little in a dead end. I guess We know now why autofac retur an IServiceCollector og the service init og startup. They re wrote the IServiceCollector, which i agere is not a viable solution. Thanks for the simple injector link. Are you saying That this Will work: services.AddScoped(provider => container.GetInstance()); Right now using the view bag, so anything would be better!!! |
This really is bad design by ms aspnetcore |
HI @Fir3pho3nixx Questions:
|
Hi, I have been playing around with this new facility and I am experiencing strange problems when deploying a dotnet core application to a Windows VM. Whenever I am running my application on my local machine, I don't experience any errors. But on a Windows VM (hosted on IIS) I am getting a
My
I am not sure if this is a Castle Windsor issue, but when hosting it on IIS on my local machine I don't experience the same error. I was hoping one of you would be able to help me out. Update I figured out it has to do with the publish configuration. When running the application in Release mode it seems to fail. When running it in Debug mode I don't experience any issues. |
Any chance you could check it against https://github.com/fir3pho3nixx/Windsor/tree/aspnet-core-windsor-final I do know we have a memory leak at the moment. |
@frankieleef please report issues here: https://github.com/fir3pho3nixx/Windsor.AspNetCore/issues |
Let me try that first before creating an issue. Thanks! |
Issue created here: https://github.com/fir3pho3nixx/Windsor.AspNetCore/issues/6 |
This addresses #120
It provides an integration with aspnet core 2.0.
Considerations for this PR:
The vanilla aspnet container consuming "Framework Configured Container" via the IServiceCollection and IApplicationBuilder interfaces.
The windsor integration as the "Application Container". These are well known framework types that serve as integration points for application developers provided by ASPNET Core 2.0.
The "application container" integrates with the "framework configured container" by using a sub dependency resolver(FrameworkConfigurationDependencyResolver). This allows seamless type resolution of framework configured components without having to "cross wire" things.
"Cross wiring" at the time of writing was attempted by SimpleInjector but it led to side effects ie. "Captive Dependencies" and "Torn Lifestyles".
We have an issue here: #243, which this hopefully addresses in how we run tests, we can switch over to 'dotnet test'. Please see this and this
Would be good if we could roll this out across the board. It will also start exposing the various target frameworks(net45, netcoreapp1.0, netcoreapp2.0) in VS2017/Resharper(latest) which is handy.
These guys both tried to implement the Microsoft Extensions Dependency Injection Abstraction(myself included but gave up). Credit for creating a foundation from which to learn from! :)