I am using the Ninject.Web library with our web forms application. It's working great except now I need to inject a dependency into a user control. What is the best way to accomplish this? Ninject.Web does not contain a base class like it does for web services, pages, and master pages.
You can make a base class for user controls yourself:
public class NinjectedUserControl : System.Web.UI.UserControl
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
RequestActivation();
}
/// <summary>
/// Asks the kernel to inject this instance.
/// </summary>
protected virtual void RequestActivation()
{
KernelContainer.Inject(this);
}
}
I have Ninject.Web's source code in my solution and I have added this class to Ninject.Web (so it can access KernelContainer, which is internal).
Related
I am trying to setup dependency injection in my ASP.NET MVC 5 app using Unity.Mvc. I followed this tutorial which explains that the class UnityConfig has a method called RegisterTypes which allows me to register my type into the container.
However, I am using Area in my project. some of my Areas need to be able to also register types into the container. These types in my area will only be used by my area but still need to be registered.
How can I register-types into my IoC container directly from my area?
You can create a separate class that inherits from UnityContainerExtension and place it in your area, like this:
public class MyAreaContainerExtension : UnityContainerExtension
{
protected override void Initialize()
{
Container.RegisterType<IDoesSomething, DoesSomething>();
}
}
Then in your startup,
container.AddNewExtension<MyAreaContainerExtension>();
Or if your extension has constructor parameters you pass to it, like configuration data it needs or instances it should use, you can create an instance of the extension and then do
container.AddExtension(theExtensionInstanceICreated);
It's a nice practice because it allows you to keep component registration closer to the classes being registered instead of having one gigantic file with dozens or even a hundred or more registrations.
Another benefit of this approach is that as component registrations become complicated you can write unit tests for these extensions that add the extension to a container and then resolve objects from the container.
You could have other components which must be registered in order for the types registered in this extension to work, but you don't want to duplicate the registrations in your extension. In that case you could make it explicit by specifying what types must already be registered, something like this:
public class MyAreaContainerExtension : UnityContainerExtension
{
protected override void Initialize()
{
AssertRequiredRegistrations();
Container.RegisterType<IDoesSomething, DoesSomething>();
}
private void AssertRequiredRegistrations()
{
AssertRequiredRegistration(typeof(ISomeOtherType));
}
private void AssertRequiredRegistration(Type type)
{
if(!Container.IsRegistered(type))
throw new Exception($"Type {type.FullName} must be registered with the container.");
}
}
I'm building a program on Unity 5 and Prism 7. I want my program to be highly modular so I want it to behave correctly if some modules are unavailable.
For this I want to mark optional dependencies with [OptionalDependency] attribute and let a classes with them to decide themselves what to do if there's null passed in constructor.
But if I mark a dependency with this attribute, Unity doesn't resolve it and just pass null instead of dependency instance, despite the module is available as usual.
How do I make dependency as really nice to have?
Or another option, how do I make Unity to not throw when dependency cannot be resolved, and just pass null instead and let the constructing classes decide what to do?
There's App.xaml.cs of my program:
public partial class App : PrismApplication
{
protected override Window CreateShell()
{
InitializeModules();
this.ShutdownMode = ShutdownMode.OnMainWindowClose;
var shell = Container.Resolve<Shell>();
this.MainWindow = shell;
return shell;
}
protected override void RegisterTypes(IContainerRegistry containerRegistry) { }
/// <summary>
/// Creating catalog of Modules from .dlls in "Modules" folder
/// </summary>
protected override IModuleCatalog CreateModuleCatalog()
{
var catalog = new DirectoryModuleCatalog() { ModulePath = #"./Modules" };
catalog.Initialize();
// by the way, modules aren't getting recognized without
// catalog.Initialize() or InitializeModules in CreateShell.
// Should it be such as that? Seems to me like no..
return catalog;
}
}
Beside main question, I appreciate any suggestions on how to make my code better in the comments under the question, because I'm a noob in Prism+Unity. Thank you!
This approach is not a good idea. Constructor injection means that the dependencies are required. Also, I don't think the OptionalDependencyAttribute works in the ctor, but rather must be applied to a property. Try making a property and applying the attribute to it.
All the code in the CreateShell method is not needed. Just return Container.Resolve<Shell>() and that's it.
Also, the modules not loading is a bug which was fixed and is available in the latest Prism CI biuld on MyGet.
So recently; I refactored Views to their own WPF Application project and I moved my ViewModel classes into their own Class Library project. This worked well for keeping my code in order. Then I realised that I didn't have the comfort of the App.xaml.cs class.
This class (for me) meant that I could declare all sorts of objects and access them application wide.
i.e: In the App.xaml.cs
public partial class App : Application
{
public myDatabaseEntities context { get; set; }
// App.xaml.cs Constructor
public App()
{
context = new myDatabaseEntities();
}
}
In some random View Model:
myDatabaseEntities context = ((App)Application.Current).context;
The above allows me to recylce the instance, and comes in particularly handy with Unity's (IoC container) version of lifetime manager.
Thing is, I'm not sure on how to achieve this behaviour within a class Library project. I'm not sure how to create a class that instantiates at runtime. And I have no clue how to pass that App class instance around to relevant classes. Any ideas on how to do this? Any help would be much appreciated.
Personally, I would keep all the "functionally" related Views and ViewModels together (next to each other). You may want to create class libraries (or modules) based for different functional parts of the application. Also, please refer to this MSDN page on building composite application using WPF and Prism.
Coming to your question, have an interface called IApplication defined something like this:
public interface IApplication
{
MyDatabaseEntities Context { get; }
}
and implement that interface on App class:
public partial class App : Application, IApplication
{
public MyDatabaseEntities Context { get; set; }
// App.xaml.cs Constructor
public App()
{
Context = new MyDatabaseEntities();
}
}
In your App.xaml.cs, as part of bootstrapping your application register this App instance with the container by calling RegisterInstance extension method on Unity container:
Container.RegisterInstance(typeof (IApplication), this, new ContainerControlledLifetimeManager());
Now, if your ViewModels take a dependency on IApplication, then they will have access to your App object and to the Context property via this interface. In future you could expose additional properties like: Dispatcher, Resources, etc from your App object through this interface.
Turns out all I needed was a regular class without the xaml front end. Then inherit the Application class. And lastly set it as the base class for app.xaml.cs. The answer is already here
We are running a webforms project at my company and I have an HttpModule that I need to resolve dependencies for.
We use the Ninject.Web library to resolve dependencies for master pages, pages, user controls, web services, and HttpHandlers. All these have base classes you can inherit from in the Ninject.Web Namespace:
MasterPageBase
PageBase
WebServiceBase
HttpHandlerBase
And a custom one we added since for some odd reason it wasn't there: UserControlBase
However I am unable to find a HttpModuleBase. There is a NinjectHttpModule, but that is not a base class, it is a real module that tries to eliminate the need to inherit from base classes in pages and user controls, but it has some bugs and we are not using it.
What is the best way to resolve my dependencies in my HttpModule?
When I google this I come up with this question on the first page -_-
Phil Haack blogged about a way to do this that makes it possible to use constructor injection and thereby avoid making your HttpModule depend directly on Ninject. In a standard NinjectHttpApplication, do the following:
Step 1
Use Nuget to find and add the HttpModuleMagic package to your web project.
Step 2
Write your HttpModule to use constructor injection:
public class MyHttpModule : IHttpModule
{
public MyHttpModule(ISomeService someService) {...}
}
Step 3
Remove the http module from your web.config:
<httpModules>
<!-- Modules will be defined via DI bindings -->
</httpModules>
Step 4
Set up bindings:
Bind<IHttpModule>().To<MyHttpModule>();
// Repeat the pattern above for any other modules.
I'm kind of amazed that nobody has answered this all day! Looks like I stumped you guys :)
Well, I solved the issue. I wrote my own custom implementation of IHttpModule and compiled it into the Ninject.Web assembly myself. Here is the source of the base class I added:
namespace Ninject.Web
{
public class HttpModuleBase : IHttpModule
{
/// <summary>
/// This method is unused by the base class.
/// </summary>
public virtual void Dispose()
{
}
/// <summary>
/// Ininitialize the module and request injection.
/// </summary>
/// <param name="context"></param>
public virtual void Init(HttpApplication context)
{
RequestActivation();
}
/// <summary>
/// Asks the kernel to inject this instance.
/// </summary>
protected virtual void RequestActivation()
{
KernelContainer.Inject(this);
}
}
}
I simply modeled it after the other base classes in the Ninject.Web assembly. It appears to be working wonderfully. Just make your HttpModule inherit from Ninject.Web.HttpModuleBase and then you are free to use property injection within your module, like this:
public class AppOfflineHttpModule : HttpModuleBase
{
[Inject]
public IUtilitiesController utilitiesController { get; set; }
...
}
I have a strategic question for my C#-project. I want to implement a plugin-concept and now struggling with the best way for the plugins to manipulate the data of the main project.
At first I created a "Master" PlugIn Project that defines the Interface for the plugins and an attribute to identify a class as a pluginclass when I load it in my main project.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public sealed class GraphViewerPlugInAttribute : Attribute
{
}
public interface IGraphViewerPlugIn
{
Panel GetRightSidePanel();
string Name();
}
This project is then referenced in the main project and the pluginclasses. The pluginclass implements the interface ...
[GraphViewerPlugIn]
public class myTestPlugIn : IGraphViewerPlugIn
{
public Panel GetRightSidePanel()
{
Panel myPanel = new Panel();
myPanel.BackColor = System.Drawing.Color.Red;
return myPanel;
}
public string Name()
{
return "TestPlugIn";
}
}
... and the main project loads all plugins that are stored in a certain directory.
This works quite well so far, I can get the special Panel from the PlugIn, but now I want to manipulate data of the main project from within the PlugIn. What would be the best way to do that?
I have some kind of data-container-class that is defined in the "Master Plugin Project" in mind. The plugin puts the data into that container and the main project will be recognized by an event that the data has changed and can now look what data has changed and then apply the changes.
Is that the right direction, what do I have to consider and which techniques (i.e. events, static classes ...) shall I use to implement that?
One approach is to add a configuration button which activates a method on the interface designed for configuration.
This method can make use of any code it would like to configure the plug in, including making it's own calls to windows forms.
If you are using windows forms or winfx, and not a custom UI, this is the ideal method because it removes all logic related to the plugin from the application itself, except for notifcation that a configure window was requested.
public interface IGraphViewerPlugIn
{
Panel GetRightSidePanel();
string Name();
void ShowConfigurationDialog();
}
Of course, you then implement ShowConfigurationDialog as such:
public void ShowConfigurationDialog()
{
Form form = new MyConfigurationDialog();
form.ShowDialog();
}
where MyConfigurationDialog is your designer created form for configuring the plugin.