Cannot add Controllers to Castle.Windsor in ASP.NET MVC - castle-windsor

Given the following setup, I have three assemblies.
Web (ASP.NET MVC 3.0 RC1)
Models
Persistence (Fluent NHibernate, Castle.Windsor)
This is my ControllerInstaller.
using System;
using System.Web.Mvc;
using Castle;
using Castle.Windsor;
using Castle.MicroKernel;
using Castle.MicroKernel.SubSystems;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
namespace Persistence.Installers
{
public class ControllerInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
AllTypes
.FromAssembly(System.Reflection.Assembly.GetExecutingAssembly())
.BasedOn<IController>()
.Configure(c => c.Named(
c.Implementation.Name.ToLowerInvariant()).LifeStyle.Transient));
}
}
}
This is my ControllerFactory...
using System;
using System.Web;
using System.Web.Mvc;
namespace Persistence.Containers
{
/// <summary>
/// Utilize Castle.Windsor to provide Dependency Injection for the Controller Factory
/// </summary>
public class WindsorControllerFactory : DefaultControllerFactory
{
private readonly Castle.Windsor.IWindsorContainer container;
public WindsorControllerFactory()
{
container = WindsorContainerFactory.Current();
}
protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
return (IController)container.Resolve(controllerType);
}
}
}
This is my Application_Start in the global.asax file..
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
// Register the Windsor Container
ControllerBuilder.Current
.SetControllerFactory(typeof(Persistence.Containers.WindsorControllerFactory));
}
I am getting the error
No component for supporting the service Project.Web.Controllers.HomeController was found
at the GetControllerInstance.
So , I'm not really sure what I am doing wrong, and why I cannot get the Controllers registered.

Your Castle Windsor setup code all belongs in your Web project. It is nothing to do with Persistence.
This is causing the problem because your ControllerInstaller is trying to register the controllers in the Persistence assembly rather than the Web assembly with the following code:
System.Reflection.Assembly.GetExecutingAssembly().
So move the IoC code to the Web project and it will find your controllers.

Related

Appinsights dependency inject in razor page with no controller

If I have an asp.net core razor page, with no controller, how do I hook the dependency injection as suggested in
#1152
and
https://learn.microsoft.com/en-us/azure/azure-monitor/app/asp-net-core#how-can-i-track-telemetry-thats-not-automatically-collected
The code as follows runs but the events are never written when I use the dependency injections methods for .net core. Other regular app insights events process fine.
namespace simplewebapp.Pages
{
public class IndexModel : PageModel
{
private readonly ILogger _logger;
private TelemetryClient telemetry;
public IndexModel(ILogger logger, TelemetryClient telemetry)
{
_logger = logger;
this.telemetry = telemetry;
telemetry.TrackEvent("IndexPage_IndexModel");
}

system.invalidoperationexception sequence contains no elements at system.linq.enumerable.first[TSource]{IEnumaberable`1 source}

I installed an updated visual studio in 2019. After that, I opened my xamarin application and ran the app. It's built successfully. Before opening the application in the emulator I got the below issue.
I was helped by the exclusion of using an inherited classes without overridden methods.
for example base class defined in net standard lib:
public class DFStorage
{
public virtual bool SaveAppTextFile(...)
{
...
}
public virtual string GetAppTextFile(...)
{
...
}
}
inherited in platform specific lib:
(without any overrides)
public class DFStorageIOS : DFStorage
{
}
App use platform class.
Overriding of one method was enough:
public class DFStorageIOS : DFStorage
{
public override bool SaveAppTextFile(...)
{
return base.SaveAppTextFile(...);
}
}

How can I see the code generated for a Razor Page when using Asp.Net Core?

With Asp.Net it was easy to see the code generated by the Razor View Engine: Add a compile error and the error page will give access to the source of the Razor Page.
This changed with Asp.Net Core, which I read somewhere creates the code in memory and does not allow access to that code easily.
Question: Someone knows a trick how to access generated Razor source code with Asp.Net Core?
Add the following class to your ASP.NET Core MVC project:
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Mvc.Razor.Compilation;
using Microsoft.AspNetCore.Mvc.Razor.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
public class CustomCompilationService : DefaultRoslynCompilationService, ICompilationService
{
public CustomCompilationService(ApplicationPartManager partManager,
IOptions<RazorViewEngineOptions> optionsAccessor,
IRazorViewEngineFileProviderAccessor fileProviderAccessor,
ILoggerFactory loggerFactory)
: base(partManager, optionsAccessor, fileProviderAccessor, loggerFactory)
{
}
CompilationResult ICompilationService.Compile(RelativeFileInfo fileInfo,
string compilationContent)
{
return base.Compile(fileInfo, compilationContent);
}
}
Override the ICompilationService added by MVC with the above class;
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<ICompilationService, CustomCompilationService>();
}
Set a break point on the Compile method of CustomCompilationService and view compilationContent.
Notes
View lookups are case sensitive. If your controller routing seeks a view named Index (Index.cshtml) but you've named your view file index (index.cshtml), you'll receive an exception:
InvalidOperationException: The view 'Index' was not found.
Artificial Stupidity provided the correct answer for ASP.NET core 1.x. For version 2.0 of the framework, one can instead use a custom razor template engine:
using Microsoft.AspNetCore.Mvc.Razor.Extensions;
using Microsoft.AspNetCore.Razor.Language;
public class CustomMvcRazorTemplateEngine : MvcRazorTemplateEngine
{
public CustomMvcRazorTemplateEngine(RazorEngine engine, RazorProject project) : base(engine, project)
{ }
public override RazorCSharpDocument GenerateCode(RazorCodeDocument codeDocument)
{
RazorCSharpDocument razorCSharpDocument = base.GenerateCode(codeDocument);
// Set breakpoint here for inspecting the generated C# code in razorCSharpDocument.GeneratedCode
// The razor code can be inspected in the Autos or Locals window in codeDocument.Source._innerSourceDocument._content
return razorCSharpDocument;
}
}
Then override the RazorTemplateEngine of the framework:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<RazorTemplateEngine, CustomMvcRazorTemplateEngine>();
}
In version 2.1 of ASP.NET Core, the RazorTemplateEngine seems to be legacy, and the above mechanism does not work anymore. The changes may have to do with the move towards precompilation of razor views, but since I am not involved in the development, I can only guess at the developers' motives.
I would now recommend inspecting the precompiled views in the **.Views.dll generated at build or publish time, depending on your project settings. I personally use Telerik's JustDecompile for this purpose.
If you really need to have a programmatic solution, you can hook into the RazorProjectEngine with a custom phase:
using Microsoft.AspNetCore.Razor.Language;
namespace Econet.PAG.UI
{
internal class DebugRazorEnginePhase : IRazorEnginePhase
{
public RazorEngine Engine { get; set; }
public void Execute(RazorCodeDocument codeDocument)
{
RazorCSharpDocument razorCSharpDocument = codeDocument.GetCSharpDocument();
// Set breakpoint here for inspecting the generated C# code in razorCSharpDocument.GeneratedCode
// The razor code can be inspected in the Autos or Locals window in codeDocument.Source._innerSourceDocument._content
}
}
}
and register it in the creation of the RazorProjectEngine
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton(s =>
{
var fileSystem = s.GetRequiredService<RazorProjectFileSystem>();
var projectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, fileSystem, builder =>
{
RazorExtensions.Register(builder);
// Roslyn + TagHelpers infrastructure
var metadataReferenceFeature = s.GetRequiredService<LazyMetadataReferenceFeature>();
builder.Features.Add(metadataReferenceFeature);
builder.Features.Add(new CompilationTagHelperFeature());
// TagHelperDescriptorProviders (actually do tag helper discovery)
builder.Features.Add(new DefaultTagHelperDescriptorProvider());
builder.Features.Add(new ViewComponentTagHelperDescriptorProvider());
builder.Phases.Add(new DebugRazorEnginePhase());
});
}
Note that except for the line adding the custom phase, the code inside AddSingleton is copied from Microsoft.Extensions.DependencyInjection.MvcRazorMvcCoreBuilderExtensions.AddRazorViewEngineServices(IServiceCollection services) in the Microsoft.AspNetCore.Mvc.Razor sources.
In a simple Console Application:
using Microsoft.AspNetCore.Razor.Language;
class Program
{
static void Main(string[] args)
{
var sourceDocument = RazorSourceDocument.Create("Hello world", "");
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var engine = RazorEngine.Create();
engine.Process(codeDocument);
var csharpDocument = codeDocument.GetCSharpDocument();
var csharp = csharpDocument.GeneratedCode;
Console.WriteLine(csharp);
}
}
Output is:
#pragma checksum "" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "7b502c3a1f48c8609ae212cdfb639dee39673f5e"
// <auto-generated/>
#pragma warning disable 1591
namespace Razor
{
#line hidden
public class Template
{
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
WriteLiteral("Hello world");
}
#pragma warning restore 1998
}
}
#pragma warning restore 1591

Does Jodd framework provide mechanism to inject petitebeans references for objects created by other frameworks

Does Jodd framework provide mechanism to inject petitebeans references for the objects created by other frameworks.
Below are scenarios
- Domain/Service objects are created by Spring Framework
- Domain objects created are by ORM Frameworks
- These objects need to be injected with Repository/DAO object (Singleton objects registered as PetiteBean via AutomagicPetiteConfigurator)
Below is sample code, after petite container is shutdown, initMethod() is invoked when pc.getBean(Greetings.class).message(null) is invoked and destroyMethod() is not invoked, can you please point me what I am doing wrong?
#PetiteBean("greetings")
public class EnglishGreetings implements Greetings {
#Override
public String message(String message) {
if (message == null) {
return "defaultMessage";
}
return message;
}
#PetiteInitMethod
public void initMethod() {
System.out.println("Entered initMethod");
}
#PetiteDestroyMethod
public void destroyMethod() {
System.out.println("Entered destroyMethod");
}
}
public class GreetingRunner {
final static Logger logger = LoggerFactory.getLogger(GreetingRunner.class);
#PetiteInject
public Greetings greetings;
public static void main(String s[]) {
jodd.log.LoggerFactory.setLoggerFactory(new Slf4jLoggerFactory());
PetiteContainer pc = new PetiteContainer();
AutomagicPetiteConfigurator configurator = new AutomagicPetiteConfigurator();
configurator.setIncludedEntries("com.rans.*");
configurator.configure(pc);
pc.shutdown();
System.out.println(pc.getBean(Greetings.class).message(null));
}
}
Destroy method has not been invoked because of lazy aspect of Petite - if bean has not been used, no destroy method will be called. The same applies to init methods. If bean is not used, Petite simple ignores it.
Now back to the question:
Does Jodd framework provide mechanism to inject petitebeans references for the objects created by other frameworks.
Technically, yes - if you overwrite it :) See PetiteProxettaContainer. You may override getBean and use 3rd party container to fetch the bean. Actually, you may override createBeanDefinitionForRegistration method to register the bean in the different container. To be honest, we might make this more obvious :)
(Sorry for late response)

How to handle RPCs in client-server PlayN game?

I'd like to use PlayN to create a client/server card game, e.g. Hearts. While I'm mostly focusing on the HTML5 output, I'd ideally like to be output-platform-agnostic in case I decide to make an Android client in the future. How should I approach the RPC mechanism?
These are the options I've thought of:
Use JSON for RPCs with get()/post() methods - write a servlet that accepts/returns JSON, and make all versions of client code use that. This seems doable, but I'm concerned about JSON's verbosity. Once I get Hearts working I'd like to move on to more complex games, and I'm worried that JSON will result in a lot of much-larger-than-necessary messages being passed back and forth between client and server. I don't actually know how to work with JSON in Java, but I assume this is doable. Are my assumptions in-line? How well does Java work with JSON?
Continue using GWT-RPC. I can do this by taking an asynchronous service interface in my core (platform-agnostic) constructor, and in my HTML main() I pass in the GWT Async interface generated by GWT.create(MyService.class) (or at least a wrapper around it). I have no idea how well this would work for non-HTML versions though. Is it possible for me to use GWT-RPC from client-side Java code directly?
Use some other form of RPC. Any suggestions?
For the GWT RPC on the Java and Android platforms, I'm currently experimenting with using gwt-syncproxy to provide Java client access to the GWT RPC methods, and I'm using Guice, Gin, and RoboGuice on their respective target platforms to inject the appropriate asynchronous service instances for the instantiated Game object.
In the core/pom.xml for a PlayN project, I include the following dependency coordinates to support DI from Gin/Guice/RoboGuice as needed:
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
Then I add #Inject annotations to any fields inside of the concrete Game implementation:
public class TestGame implements Game {
#Inject
TestServiceAsync _testService;
...
}
In the html/pom.xml, I include the dependency coordinates for Gin:
<dependency>
<groupId>com.google.gwt.inject</groupId>
<artifactId>gin</artifactId>
<version>1.5.0</version>
</dependency>
And I create TestGameGinjector and TestGameModule classes:
TestGameGinjector.java
#GinModules(TestGameModule.class)
public interface TestGameGinjector extends Ginjector {
TestGame getGame();
}
TestGameModule.java
public class TestGameModule extends AbstractGinModule {
#Override
protected void configure() {
}
}
Since at the moment, I'm only injecting the TestServiceAsync interface, I don't need to put any implementation in the TestGameModule.configure() method; Gin manages instantiation of AsyncServices for me via GWT.create().
I then added the following to TestGame.gwt.xml
<inherits name='com.google.gwt.inject.Inject'/>
And finally, I made the following changes to TestGameHtml.java
public class TestGameHtml extends HtmlGame {
private final TestGameGinjector _injector = GWT.create(TestGameGinjector.class);
#Override
public void start() {
HtmlPlatform platform = HtmlPlatform.register();
platform.assetManager().setPathPrefix("test/");
PlayN.run(_injector.getGame());
}
}
And this pretty much covers the HTML5 platform for PlayN.
For the Java platform, I add the following dependency coordinates to java/pom.xml:
<dependency>
<groupId>com.gdevelop.gwt.syncrpc</groupId>
<artifactId>gwt-syncproxy</artifactId>
<version>0.4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>3.0-rc2</version>
</dependency>
Do note that the gwt-syncproxy project on Google Code does not contain a pom.xml. I have a mavenized version of gwt-syncproxy forked and available via git at https://bitbucket.org/hatboyzero/gwt-syncproxy.git. You should be able to clone it, run mvn clean package install to get it into your local Maven repository.
Anyways, I created a TestGameModule.java for the Java platform as follows:
public class TestGameModule extends AbstractModule {
#Override
protected void configure() {
bind(TestServiceAsync.class).toProvider(TestServiceProvider.class);
}
public static class TestServiceProvider implements Provider<TestServiceAsync> {
public TestServiceAsync get() {
return (TestServiceAsync) SyncProxy.newProxyInstance(
TestServiceAsync.class,
Deployment.gwtWebPath(), // URL to webapp -- http://127.0.0.1:8888/testgame
"test"
);
}
}
}
And I modified TestGameJava.java as follows:
public class TestGameJava {
public static void main(String[] args) {
Injector _injector = Guice.createInjector(new TestGameModule());
JavaPlatform platform = JavaPlatform.register();
platform.assetManager().setPathPrefix("test/images");
PlayN.run(_injector.getInstance(TestGame.class));
}
}
I went through a similar exercise with the Android platform and RoboGuice -- without going into tremendous detail, the relevant changes/snippets are as follows:
pom.xml dependencies
<dependency>
<groupId>com.gdevelop.gwt.syncrpc</groupId>
<artifactId>gwt-syncproxy</artifactId>
<version>0.4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.roboguice</groupId>
<artifactId>roboguice</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>3.0-rc2</version>
<classifier>no_aop</classifier>
</dependency>
TestGameApplication.java
public class TestGameApplication extends RoboApplication {
#Override
protected void addApplicationModules(List<Module> modules) {
modules.add(new TestGameModule());
}
}
TestGameModule.java
public class TestGameModule extends AbstractModule {
#Override
protected void configure() {
bind(TestServiceAsync.class).toProvider(TestServiceProvider.class);
}
public static class TestServiceProvider implements Provider<TestServiceAsync> {
public TestServiceAsync get() {
return (TestServiceAsync) SyncProxy.newProxyInstance(
TestServiceAsync.class,
Deployment.gwtWebPath(), // URL to webapp -- http://127.0.0.1:8888/testgame
"test"
);
}
}
}
TestGameActivity.java
public class TestGameActivity extends GameActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
final Injector injector = ((RoboApplication) getApplication()).getInjector();
injector.injectMembers(this);
super.onCreate(savedInstanceState);
}
#Override
public void main(){
platform().assetManager().setPathPrefix("test/images");
final Injector injector = ((RoboApplication) getApplication()).getInjector();
PlayN.run(injector.getInstance(TestGame.class));
}
}
That's a quick and dirty rundown of how I got Gin/Guice/RoboGuice + GWT working in my project, and I have verified that it works on both Java and HTML platforms beautifully.
Anyways, there's the GWT approach to providing RPC calls to multiple PlayN platforms :).