How to use Ninject.Web.PageBase alongside another, custom .NET PageBase - asp.net

I am trying to get Ninject working with a WebForms application that already has a custom PageBase object. But, I don't know for sure if I can use Ninject's PageBase object alongside another, custom PageBase. I've been searching for a while now to see if I could find an answer to this problem, or to learn how to do it, but all I've found is this:
I've hacked together an alternative using a shared base class that
derives from Page. It looks roughly like this
public abstract class PageBase : Page
{
public IKernel Kernel { get; private set; }
public PageBase() { Kernel = ...; }
public void Page_Init() { Kernel.Inject(this); }
}
This will allow you to property and method injection on any pages that
inherit from PageBase. Note that the constructor is incomplete --
you'll have to access the kernel in some static fashion. You should
be able to read it from the HttpApplication somehow.
(source: http://groups.google.com/group/ninject/browse_thread/thread/317fc48387399aa6, linked from Ninject with ASP.Net webforms and MVC):
This looks like it might work for me because it appears that I could apply this code to the existing, custom PageBase. But, I am hung up on the part in which the author says, "... the constructor is incomplete -- you'll have to access the kernel in some static fashion."
Does anyone have any idea what that sentence means, and how one might go about accessing the Ninject kernel in a static fashion?

You do not need to derive from a Ninject page base. You can alternatively use the NinjectHttpModule.
https://github.com/ninject/ninject.web/blob/master/src/Ninject.Web/NinjectHttpModule.cs

Related

ASP.NET Core MVC application dependency injection issue when using BaseController

Recently i tried to create a MVC application using ASP.NET Core 2.0 and i had some values defined in appsettings.json,
"MySettings": {
"WebApiBaseUrl": "http://localhost:6846/api/"
}
In order to read these values i have added
services.Configure<MySettingsModel>(Configuration.GetSection("MySettings"));
above line in ConfigureServices method in Startup.cs
and in my home controller i have added
private readonly IOptions<MySettingsModel> appSettings;
public HomeController(IOptions<MySettingsModel> app)
{
appSettings = app;
}
MySettingsModel class is just a model with property same as key define in appsettings.json.
by this method i'm able to read the value of this key.
Now my issue is that i want to use this key in many controllers so i don't want to repeat this code in every controller so what i did was i created a BaseConntroller, added its constructor and i got my values there. But when i inherit other controllers with my BaseController , it throws me an error and tells me to generate it's constructor, so basically it tells me to add constructor in every controller which is what i wanted to avoid.
How can i achieve this?
You can see the image for the error
And these are the potential fixes that it shows me.
This is just basic C# inheritance. Derived classes must re-implement constructors on base classes (at least the ones you want or need). The only exception is the empty constructor, which is implicit. In other words, you simply need:
public class HomeController : BaseController
{
public HomeController(IOptions<MySettingsModel> app)
: base(app)
{
}
And, of course, you need to change the accessibility of the base class field to protected instead of private. Otherwise, derived classes will not be able to access it.
Of course, this doesn't really save you that much. However, there's no free lunch here. Like I said, this is a limitation of C#, itself, so you have no choice. Although, it's worth mentioning, that while this can sometimes be annoying, it's actually a kind of useful feature of C#. You can look at any class and see exactly what constructors it has available, without having to trace down all its ancestors.
Actually, there is a good solution here:
https://stackoverflow.com/a/48886242/2060975
I am mostly using this method.
[Authorize]
[ApiController]
public abstract class ApiControllerBase : ControllerBase
{
private IOptions<AppSettings> _appSettings;
protected IOptions<AppSettings> appSettings => _appSettings ?? (_appSettings = (IOptions<AppSettings>)this.HttpContext.RequestServices.GetService(typeof(IOptions<AppSettings>)));
...
}
I hope it helps someone:)

Best place to create global object in ASP.NET MVC

I would like to implement ConcurrentQueue object in my ASP.NET MVC app. The ConcurrentQueue object will be shared between sessions and should be created once. What is the best place to create ConcurrentQueue in ASP.NET MVC?
Any class you choose can hold an instance of it, however it would make most sense to couple it within a class that is responsible for whatever functionality the queue is used for.
For example a Cache class:
public class MyCache
{
public static ConcurrentQueue Queue { get; private set; }
static MyCache()
{
Queue = new ConcurrentQueue();
}
}
This will initialize it the first time the MyCache class is used. If you want finer grain control, you could create an Initialize method that your Global.asax.cs file calls on app start.
You could:
Create it in a static constructor, so it's created only when some code actually uses the type
Global.asax.
Use WebActivator - you won't pollute Global.asax file, and you can create the queue in different assembly.
File Global.asax.cs, protected void Application_Start() method overload.
Another approach would be making a Singleton/static class.

Setting up Non-Public Properties using Moq Functional Syntax

Anyone know if the Moq functional syntax supports setups for Non-Public properties? I noticed that it doesn't work.
NOTE: This is for the functional syntax.
public class Foo
{
public virtual int FooProperty { get; protected set; }
}
This doesn't throw an error, but fails to mock FooProperty
Mock.Of<Foo>(x => x.FooProperty == 1);
The regular syntax works fine.
var mockFoo = new Mock<Foo>(); mockFoo.SetupGet(x=>x.FooProperty)
.Returns(1)
It might be worth looking at the Pex/Moles tool from Microsoft Research. Moles is used to create accessors for non-public stuff.
It will support mocking of internal properties if you add an assembly attribute to the assembly containing the class under test (add to AssemblyInfo.cs):
// This assembly is the default dynamic assembly generated Castle DynamicProxy,
// used by Moq. Paste in a single line.
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
(You would also have to add an InternalsVisibleTo entry for your test project, of course.)
If you do this, you can mock any internal property in the assembly to which this is added. If you want to mock private or protected properties, I'm pretty sure there's no way to do that directly. If they're protected, you could create a Dummy inheritor and give it public methods or properties that access/manipulate its protected members. For private, there's really nothing you can do, I believe.

How can I improve our CM.AppSettings references

ASP.NET 3.5
Classes throughout our solution referenced ConfigurationManater.AppSettings[""] to get appSettings (from web.config).
We decided we weren't happy with that. Folks were mistyping appSetting key names in code (which compiled fine), and it was cumbersome to track usages. And then there's the duplicated strings throughout the codebase as you reference the same appSettings all over the place.
So, we decided that only one class would be allowed to reference the ConfigurationManager, and the rest of the solution would reference that class when it needed the value of a certain appSetting. ConfigurationManater.AppSettings[""] was static, so we exposed a bunch of static read-only properties off of our single Settings class.
public class Settings {
public static string Foo {
get {
return ConfigurationManager.AppSettings["Foo"];
}
}
}
That worked pretty well, until we needed to mock the settings in our tests. We created an interface to enable our mocking (was this a mistake of any kind?).
public interface ISettings {
string Foo {
get;
set;
}
}
public class Settings : ISettings {
public string Foo {
get {
return ConfigurationManager.AppSettings["Foo"];
}
}
}
And now we're injecting the ISettings instance as a dependency of the objects which use settings values (the class/interface are in a project that everyone can reference without problems).
In places where we can't inject an existing instance (e.g. Global.asax), we construct a new instance into a static field.
Given all of that, what would you recommend we change, and why?
Using an interface to represent configuration is a good idea. But your implementation looks a little off.
Joshua Flanagan wrote about writing application configuration code in a way that specific configuration sections can be injected into your code. This is a good idea, as it really decouples your code from worrying about details behind configuration. Have a read.
I think this will address the issue you are having re. testability.

Implementing a WebControl factory in ASP.NET

I need to implement the classic Factory Method pattern in ASP.NET to create server controls dynamically.
The only way I've found to create .ascx controls is to use the LoadControl method of the Page/UserControl classes. I find it messy however to link my factory with a page or to pass a page parameter to the factory.
Does anybody know of another method to create such controls (such as a static method somewhere i'd have overlooked) ?
Thanks.
In the end, I decided to pass the page as a parameter to the factory. To make calls to the factory method easier, I changed the factory class from a singleton to a common class, and I passed the page to the constructor:
public ControlsFactory
{
private Page _containingPage;
public ControlsFactory(Page containingPage)
{
_containingPage = containingPage;
}
public CustomControlClass GetControl(string type)
{
... snip ...
CustomControlClass result = (CustomControlClass)_containingPage.LoadControl(controlLocation);
return result;
}
}
Since I have to instantiate many controls on each page with the factory, this is probably the most concise and usable way to implement the pattern.
Well after opening up reflector, the LoadControl function that is being used in Page is available in any TemplateControl.
Inside the actual LoadControl uses internal methods in BuildManager, so I don't think there's a way to use static methods without using reflection.
Well at least you don't need to pass a page around. Subclassing TemplateControl would work.

Resources