I have an issue with some compiler warnings I am getting when using T4 MVC (along with MVC3 RC2).
Say you have the following classes….
public partial class ParentController { }
public partial class ChildController : ParentController { }
T4MVC will generate something like…
public partial class ParentController
{
[GeneratedCode("T4MVC", "2.0")]
public readonly string Name = "Parent";
}
public partial class ChildController
{
[GeneratedCode("T4MVC", "2.0")]
public readonly string Name = "Child";
}
Which causes a compiler warning to occur suggesting the use of the ‘new’ keyword on the Name property in the derived class.
Is there something that can be done (short of turning the warning off completely) to get around this issue?
You could always drag the T4 templates into your own project and customize them to your needs.
Related
I have a question regarding creating a class diagram where I have used dependency injection.
I have following code example:
public class ReservationController : ApiController
{
private readonly IGetReservationService _getReservationService;
public ReservationController(IGetReservationService getReservationService)
{
_getReservationService = getReservationService;
}
// GET list of all reservations
public List<ReservationViewModel> GetReservations()
{
return _getReservationService.GetReservations();
}
// GET single reservation by id
public List<ReservationViewModel> GetReservation(string reservationNumber)
{
return _getReservationService.GetReservation(reservationNumber);
}
}
Here you see that the controller (ReservationController) getting the IGetReservationService injected in the constructor. When creating the relationship between the controller and the interface, do you then use a dependency or an association?
My guess is that it should be a dependency since we are using dependency injection?
Good day.
Yes, this is a dependency. An association is used if you have object references (e.g. for a property).
I want to implement fluent api to my mvc sites. I got the basics.
So implement object library such as:
public class UIElement{/*...*/}
public class ButtonBase : UIElement{/*...*/}
public class LinkButton : ButtonBase {/*...*/}
public static class Extensions
{
public static T UIElementMethod<T>(this T element, string title)
where T : UIElement
{
return element;
}
public static T ButtonBaseMethod<T>(this T element, string title)
where T : ButtonBase
{
return element;
}
public static T LinkButtonMethod<T>(this T element, string title)
where T : LinkButton
{
return element;
}
}
But how to use it in razor view without some flush method calling.
#Html.UIproject().LinkButton()
.UIElementMethod("asd")
.ButtonBaseMethod("asd")
.LinkButtonMethod("asd")
But it returns the name of the class. I tried to make an implicit operator to MvcHtmlString but it's not called.
Any idea how to achieve this. How to know it's the and of the chain. I like the way how the Kendo UI work.
Thanks,
Péter
Your UIElement classes need to implement the IHtmlString interface. This interface's ToHtmlString method gets called by Razor and should return an HTML-encoded string.
So I would implement this on the abscract base UIElement and create RenderHtml method which can be implemented by the concrete LinkButton, etc. classes:
public abstract class UIElement : IHtmlString
{
public string ToHtmlString()
{
return RenderHtml(); // This should return an HTML-encoded string.
}
public override string ToString()
{
return ToHtmlString();
}
protected abstract string RenderHtml();
}
If you check KendoUI in Reflector/JustDecompile/dotPeek in the WidgetBase class you will see the same pattern.
I haven't tried it, in this particular situation, but you might be able to use an implicit cast to convert from a fluent builder to the object you need (see this blog).
We have an MVC3 controller in which there is some 'common' work that we rolled into the controller constructor. Some of that common work is done by a losely coupled class (say ourService) that's dynamically resolved through Unity (for IoC / Dependency injection). ourService is null (i.e. not resolved) in the Controller's constructor BUT it's properly resolved in the usual Controller methods. The simple demo code below shows the issue:
public class Testing123Controller : BaseController
{
[Dependency]
public IOurService ourService { get; set; }
public Testing123Controller()
{
ourService.SomeWork(1); // ourService=null here !!
...
}
public ActionResult Index()
{
ourService.SomeWork(1); // resolved properly here here !!
...
}
...
}
Question:
Why is there this different in Unity resolution behavior? I would expect consistent behavior.
How can I fix it so Unity resolves this even in the controller's contructor?
The way we've setup Unity 2.0 is :
Global.asax
Application_Start()
{
...
Container = new UnityContainer();
UnityBootstrapper.ConfigureContainer(Container);
DependencyResolver.SetResolver(new UnityDependencyResolver(Container));
...
}
public static void ConfigureContainer(UnityContainer container)
{
...
container.RegisterType<IOurService, OurService>();
...
}
IOurService.cs
public interface IOurService
{
bool SomeWork(int anInt);
}
OurService.cs
public class OurService: IOurService
{
public bool SomeWork(int anInt)
{
return ++anInt; //Whew! Time for a break ...
}
}
As a basic principle of classes, before an instance property can be set, the instance has to be instantiated.
Unity needs to set the dependency property, but it can't do so until the instance has been fully instantiated - i.e. the constructor must have completed executing.
If you are referencing the dependency property in the constructor, then this is too early - there is no way for Unity to have set it yet - and therefore it will be unset (i.e. null).
If you need to use the dependency in the constructor, then you must use constructor injection. Although in general, using constructor injection is usually the better method anyway:
public class Testing123Controller : BaseController
{
public IOurService ourService { get; set; }
public Testing123Controller(IOurService ourService)
{
this.ourService = ourService;
this.ourService.SomeWork(1); // ourService no longer null here
...
}
public ActionResult Index()
{
ourService.SomeWork(1); // also resolved properly here
...
}
...
}
Note: In the example I left ourService as a publicly gettable & settable property in case other parts of your code need to access it. If on the other hand it is only accessed within the class (and had only been made public for Unity purposes), then with the introduction of constructor injection, it would be best to make it a private readonly field.
You are using property injection (by using the Dependency attribute) rather than constructor injection so the dependency is not resolved until after the controller is instantiated. If you want to have access to the dependency is the constructor, just add it to the ctor:
private readonly IOurService _ourService { get; set; }
public Testing123Controller(IOurService ourService)
{
_ourService = ourService;
_ourService.SomeWork(1); // ourService=null here !!
...
}
I'm afraid that for Unity to work on the constructor, the instance itself must be resolved using Unity. The fact that the Service property is null in the constructor supports this idea. If you call the Controller yourself (NOT with Unity), Unity has no time to resolve the property.
I have the following classes -
public abstract class BusinessObject { }
public abstract class Form: BusinessObject { }
public abstract class BillableForm: Form { }
public class MembershipForm: BillableForm { }
public abstract class Dto<T>: where T: BusinessObject { }
public abstract class InboxDto<T>: Dto<T> where T: Form { }
public class MembershipFormDto: InboxDto<MembershipForm> { }
And I have the following views -
membershipform.cshtml:
#model AdminSite.Models.MembershipFormDto
#{
Layout = "~/Views/Inbox/Shared/_LayoutForm.cshtml"
}
_LayoutForm.cshtml:
#model InboxDto<Form>
When I land on the membershipform.cshtml page, I get the following exception stating:
The model item passed into the dictionary is of type 'AdminSite.Models.MembershipFormDto', but this dictionary requires a model item of type 'AdminSite.Infrastructure.Models.InboxDto`1[BusinessLogic.Inbox.Form]'.
From everything I can tell, MembershipFormDto IS-A InboxDto of type MembershipForm, where MembershipForm IS-A Form. What gives?
This turned out to be an issue of covariance.
I added the following interface -
public interface IInboxDto<out T>
and modified the InboxDto class to implement that interface -
public abstract class InboxDto<T>: Dto<T>, IInboxDto<T> where T: Form { }
In short, covariance is going from a more defined type to a less defined type; specifically referencing a more defined object with a less defined reference. The reason the compiler complains is it's preventing a scenario like this:
List<String> instanciatedList = new List<String>;
List<Object> referenceList = instanciatedList;
referenceList.add(DateTime);
The final line makes sense, a DateTime IS-A Object. We've said referenceList is a List of Object. However it's instanciated as a List of String. A List of Object is more permissive than a List of String. Suddenly our guarantees from new List<String> are being ignored.
However the out and in keywords for Interface definitions tells the compiler to relax, we know what we're doing and understand what we're getting ourselves into.
More information.
Preliminaries
I'm using Ninject.MVC3 2.2.2.0 Nuget Package for injecting into my controller an implementation of a IDomain Interface that separates my Business Logic (BL) using an Factory approach.
I'm registering my Ninject Modules in the preconfigured NinjectMVC3.cs using:
private static void RegisterServices(IKernel kernel)
{
var modules = new INinjectModule[]
{
new DomainBLModule(),
new ADOModule()
};
kernel.Load(modules);
}
I'm trying to avoid the fatal curse of the diabolic Service Locator anti-pattern.
The Domain Class uses a DBContext that i'm trying to inject an interface implementation too, via an IDBContext, with the following scenario:
IDomainBLFactory:
public interface IDomainBLFactory
{
DomainBL CreateNew();
}
DomainBLFactory:
public class DomainBLFactory : IDomainBLFactory
{
public DomainBL CreateNew()
{
return new DomainBL();
}
}
In the controller's namespace:
public class DomainBLModule : NinjectModule
{
public override void Load()
{
Bind<IDomainBLFactory>().To<DomainBLFactory>().InRequestScope();
}
}
At this point i can inject the IDomainBLFactory implementation into my controller using Ninject Constructor Injection without any problem:
public class MyController : Controller
{
private readonly IDomainBLFactory DomainBLFactory;
// Default Injected Constructor
public MyController(IDomainBLFactory DomainBLFactory)
{
this.DomainBLFactory = DomainBLFactory;
}
... (use the Domain for performing tasks/commands with the Database Context)
}
Now my central problem.
In the DomainBL implementation, i will inject the dependency to a particular DBContext, in this case ADO DBContext from Entity Framework, again, using a IDBContextFactory:
IDbDataContextFactory
public interface IDbDataContextFactory
{
myADOEntities CreateNew();
}
DbDataContextFactory
public class DbDataContextFactory : IDbDataContextFactory
{
public myADOEntities CreateNew()
{
return new myADOEntities ();
}
}
ADOModule
public class ADOModule : NinjectModule
{
public override void Load()
{
Bind<IDbDataContextFactory>().To<DbDataContextFactory>().InRequestScope();
}
}
Now in the DomainBL implementation I faced the problem of injecting the necessary interface for the DBContext Object Factory:
public class DomainBL
{
private readonly IDbDataContextFactory contextFactory;
**** OPS, i tried to understand about 10+ Stackoverflow articles ***
...
}
What have I tried?
To Use the constructor Injection. But I don't know what to inject in the call for the Factory CreateNew() in the IDBContextFactory. For clear:
public class DomainBLFactory: IDomainBLFactory
{
// Here the constructor requires one argument for passing the factory impl.
public DomainBL CreateNew()
{
return new DomainBL(?????) // I need a IDBContextFactory impl to resolve.
//It's not like in the MVC Controller where injection takes place internally
//for the controller constructor. I'm outside a controller
}
}
In this Useful Post, our unique true friend Remo Gloor describes in a comment a possible solution for me, citing: "Create an interface that has a CreateSomething method that takes everything you need to create the instance and have it return the instance. Then in your configuration you implement this interface and add an IResolutionRoot to its constructor and use this instace to Get the required object."
Questions: How do I implement this in a proper way using Ninject.MVC3 and my modest Domain Class approach? How do I Resolve the IResolutionRoot without be punished for relaying in the Service Locator anti-pattern?
To Use the property injection for an IDBContexFactory. In the course of learning and reading all the contradictory points of view plus the theoretical explanations about it, I can deduce it's not a proper way of doing the injection for my DBContexFactory class code. Nevermind. It doesn't work anyway.
public class DomainBL
{
[Inject]
public IDbDataContextFactory contextFactory
{
get;
set;
}
//Doesn't works, contextFactory is null with or without parameterless constructor
.... (methods that uses contextFactory.CreateNew()....
}
Question: What am I missing? Even if this approach is wrong the property is not injecting.
Be cursed. Use a DependencyResolver and live with the stigmata. This works and I will remain in this approach until a proper solution appears for me. And this is really frustrating because the lack of knowledge in my last 10 days effort trying to understand and do things right.
public class DomainBL
{
private readonly IDbDataContextFactory contextFactory;
this.contextFactory = DependencyResolver.Current.GetService<IDbDataContextFactory>();
//So sweet, it works.. but i'm a sinner.
}
Question: Is there a big mistake in my understanding of the Factory Approach for the injection of interfaced implementations and using a Domain Driven Approach for taking apart the Business Logic? In the case I'm wrong, what stack of patterns should I implement with confidence?
I saw before a really big quantity of articles and blogs that does not ask this important question in a open a clear way.
Remo Gloor introduces the Ninject.Extensions.Factory for the Ninject 3.0.0 RC in www.planetgeek.ch/2011/12/31/ninject-extensions-factory-introduction.
Question: Will this extension work coupled with Ninject.MVC3 for general porpouse?. In such case it should be my hope for the near future.
Thank you all in advance for your guidance and remember we appreciate your kind help. I think a lot of people will find this scenario useful too.
I don't really get the purpose of your factories. Normally, you have exactly one ObjectContext instance for one request. This means you don't need the factory and can simply bind myADOEntities in Request scope and inject it into your DomainBL without adding the factories:
Bind<myADOEntities>().ToSelf().InRequestScope();
Bind<DomainBL>().ToSelf().InRequestScope();
And Yes the factory and mvc extrensions work together.
Here's an implementation of a generic IFactory to solve the problem without resorting to the ServiceLocator anti-pattern.
First you define a nice generic factory interface
public interface IFactory<T>
{
T CreateNew();
}
And define the implementation which uses ninject kernel to create the objects requested
class NinjectFactory<T> : IFactory<T>
{
private IKernel Kernel;
public NinjectFactory( IKernel Kernel )
{
this.Kernel = Kernel;
}
public T CreateNew()
{
return Kernel.Get<T>();
}
}
Binding to your factory using the following
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<myADOEntities>().ToSelf();
kernel.Bind<DomainBL>().ToSelf();
kernel.Bind(typeof(IFactory<>)).To(typeof(NinjectFactory<>));
}
You can now do the following in your controller.
public class MyController : Controller
{
private readonly IFactory<DomainBL> DomainBLFactory;
public MyController( IFactory<DomainBL> DomainBLFactory )
{
this.DomainBLFactory = DomainBLFactory;
}
// ... (use the Domain for performing tasks/commands with the Database Context)
}
And in your DomainBL
public class DomainBL
{
IFactory<myADOEntities> EntitiesFactory;
public DomainBL( IFactory<myADOEntities> EntitiesFactory )
{
this.EntitiesFactory = EntitiesFactory;
}
// ... (use the Entities factory whenever you need to create a Domain Context)
}