I am developing a .Net Web Forms project structure and I decided to use Unity as a DI framework for the application.
MSDN-Resolving in Asp.Net states that in order to inject dependencies in my project I need to build up the initial object which is created outside of the DI container. That being said we come to the question.
The attribute annotations such as [Dependency]
are classes extending the Attribute
class. In order to use them, another namespace must be included in the declaring class, thus making our class dependent on the Microsoft.Practices.Unity.DependencyAttribute
class. So now, even though our class might not be aware of the implementation of IMyInterface that it uses, it has to be aware of the concrete implementation of the Dependency class? What is it that I am missing here? If we were to change the DI framework, we would need to remove all the annotations throughout the project.
Is there a way to avoid this kind of declaration (configuration files or what-not) outside of the container?
EDIT --> Code here
/*This is the abstract base class where I want the dependency injection to occur*/
public abstract class BasePage : System.Web.UI.Page
{
private IMyService _dtService;
public IMyService DtService
{
get { return _dtService; }
set { _dtService = value; }
}
}
The Default.aspx code behind
public partial class _Default : BasePage
{
public _Default( )
{
}
protected void Page_Load(object sender, EventArgs e)
{
try
{
DataClass dt = DtService.GetDataById(2);
lblWhatever.Text = dt.Description;
}
}
}
Global code behind
public class Global : System.Web.HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
IUnityContainer myContainer = HttpContext.Current.Application.GetDIContainer();
myContainer.RegisterType<IMyService,MyServiceClient>(new
InjectionConstructor("MyServiceWsEndpoint"));
// I have tried this with BasePage too
myContainer.RegisterType<_Default>(new InjectionProperty("DtService"));
}
}
And the module
public class UnityHttpModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += OnPreRequestHandlerExecute;
}
public void Dispose() { }
private void OnPreRequestHandlerExecute(object sender, EventArgs e)
{
IHttpHandler currentHandler = HttpContext.Current.Handler;
/*This does not work*/
HttpApplicationStateExtensions.GetDIContainer(HttpContext.Current.Application).BuildUp(
currentHandler.GetType(), currentHandler);
/* While this works*/
HttpApplicationStateExtensions.GetDIContainer(HttpContext.Current.Application).BuildUp<_Default>((_Default)currentHandler);
var currentPage = HttpContext.Current.Handler as Page;
if (currentPage != null)
{
currentPage.InitComplete += OnPageInitComplete;
}
}
}
The code inside the module is reached every time. The line Does INDEED work when I use the [Dependency]
Attribute.
Using these frameworks, you can take all the monobehaviours of your scene in one single place and let the framework pass the dependencies of these monobehaviours. Extenject Dependency Injection IOC is a very popular and widely used framework for Unity.
Dependency Injection (or inversion) is basically providing the objects that an object needs, instead of having it construct the objects themselves. It is a useful technique that makes testing easier, as it allows you to mock the dependencies.
Dependency Injection (DI) is a software design pattern that allows us to develop loosely coupled code. DI is a great way to reduce tight coupling between software components. DI also enables us to better manage future changes and other complexity in our software. The purpose of DI is to make code maintainable.
Dependency injection is a pattern to allow your application to inject objects on the fly to classes that need them, without forcing those classes to be responsible for those objects. It allows your code to be more loosely coupled, and Entity Framework Core plugs in to this same system of services.
Yes, peppering code with Dependency attributes tightly couples the implementation to the container.
There are a few ways to determine what properties to inject:
One way to get around the use of attributes is to register all of the pages and specify programmatically what properties to inject and supply overrides as needed to BuildUp
:
IUnityContainer container = new UnityContainer();
// Assume we have a logger we are injecting
container.RegisterType<ILogger, Logger>(new ContainerControlledLifetimeManager());
// Register the Dependency Properties for the Page 'MyPage'.
// Property names on MyPage are "Logger"
container.RegisterType<MyPage>(new InjectionProperty("Logger"));
// ...later
IHttpHandler currentHandler = HttpContext.Current.Handler;
// Perform Property Injection.
// Logger will be injected from the existing container registration.
container.BuildUp(currentHandler.GetType(), currentHandler);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With