Using StructureMap[4.7.0] Setter Injection in my MVC5 Controller - asp.net-mvc-5

I am trying to inject the IApplicationConfigurationSection implementation into this MVC5 Controller, so that I can have access to some of the information (various strings) from my web.config custom section in all of my views:
public class BaseController : Controller
{
public IApplicationConfigurationSection AppConfig { get; set; }
public BaseController()
{
ViewBag.AppConfig = AppConfig; // AppConfig is always null
}
}
I want to use setter injection so I don't have to clutter up my derived Controller constructors with parameters that they don't really care about.
Note: If there is a better way to inject base class dependencies, please let me know. I admit I may not be on the right track here.
In my Global.asax I load my StructureMap configurations:
private static IContainer _container;
protected void Application_Start()
{
_container = new Container();
StructureMapConfig.Configure(_container, () => Container ?? _container);
// redacted other registrations
}
My StructureMapConfig class loads my registries:
public class StructureMapConfig
{
public static void Configure(IContainer container, Func<IContainer> func)
{
DependencyResolver.SetResolver(new StructureMapDependencyResolver(func));
container.Configure(cfg =>
{
cfg.AddRegistries(new Registry[]
{
new MvcRegistry(),
// other registries redacted
});
});
}
}
My MvcRegistry provides the mapping for StructureMap:
public class MvcRegistry : Registry
{
public MvcRegistry()
{
For<BundleCollection>().Use(BundleTable.Bundles);
For<RouteCollection>().Use(RouteTable.Routes);
For<IPrincipal>().Use(() => HttpContext.Current.User);
For<IIdentity>().Use(() => HttpContext.Current.User.Identity);
For<ICurrentUser>().Use<CurrentUser>();
For<HttpSessionStateBase>()
.Use(() => new HttpSessionStateWrapper(HttpContext.Current.Session));
For<HttpContextBase>()
.Use(() => new HttpContextWrapper(HttpContext.Current));
For<HttpServerUtilityBase>()
.Use(() => new HttpServerUtilityWrapper(HttpContext.Current.Server));
For<IApplicationConfigurationSection>()
.Use(GetConfig());
Policies.SetAllProperties(p => p.OfType<IApplicationConfigurationSection>());
}
private IApplicationConfigurationSection GetConfig()
{
var config = ConfigurationManager.GetSection("application") as ApplicationConfigurationSection;
return config; // this always returns a valid instance
}
}
I have also "thrown my hands up" and tried using the [SetterProperty] attribute on the BaseController - that technique failed as well.
Despite my best efforts to find a solution, the AppConfig property in my controller's constructor is always null. I thought that
`Policies.SetAllProperties(p => p.OfType<IApplicationConfigurationSection>());`
would do the trick, but it didn't.
I have found that if I discard setter injection and go with constructor injection, it works as advertised. I'd still like to know where I'm going wrong, but I'd like to stress that I'm not a StructureMap guru - there may be a better way to avoid having to constructor-inject my base class dependencies. If you know how I should be doing this but am not, please share.

While constructor injection in this scenario appears to be the better solution to the stated problem as it follows The Explicit Dependencies Principle
Methods and classes should explicitly require (typically through method parameters or constructor parameters) any collaborating objects they need in order to function correctly.
The mention of only needing to access the AppConfig in your views leads me to think that this is more of an XY problem and a cross cutting concern.
It appears that the controllers themselves have no need to use the dependency so stands to reason that there is no need to be injecting them into the controller explicitly just so that the dependency is available to the View.
Consider using an action filter that can resolve the dependency and make it available to the View via the same ViewBag as the request goes through the pipeline.
public class AccessesAppConfigAttribute : ActionFilterAttribute {
public override void OnActionExecuting(ActionExecutingContext filterContext) {
var resolver = DependencyResolver.Current;
var appConfig = (IApplicationConfigurationSection)resolver.GetService(typeof(IApplicationConfigurationSection));
filterContext.Controller.ViewBag.AppConfig = appConfig;
}
}
This now makes the required information available to the views with out tight coupling of the controllers that may have a use for it. Removing the need to inject the dependency into derived classes.
Either via adorning Controller/Action with the filter attribute
[AccessesAppConfig] //available to all its actions
public class HomeController : Controller {
//[AccessesAppConfig] //Use directly if want to isolate to single action/view
public ActionResult Index() {
//...
return View();
}
}
or globally for all requests.
public class FilterConfig {
public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
filters.Add(new AccessesAppConfigAttribute());
}
}
At this point it really does not matter which IoC container is used. Once the dependency resolver has been configured, Views should have access to the required information in the ViewBag

Related

Can I register Orchard resources in an HtmlHelper?

I am aware that this violates the MVC principle and best practices.
I have a whole bunch of custom Angular components that each take a whole bunch of optional parameters and each require a different remote stylesheet and javascript file. I would like to render these with an HtmlHelper without having to manually include the right resources everywhere I use them.
I was hoping that this would do the trick but it doesn't
public static class HtmlExtensions
{
private static IResourceManager _resourceManager;
// Executed in the Activated method of an OrchardShellEvents implementation
public static void SetResourceManager(IResourceManager resourceManager)
{
_resourceManager = resourceManager;
}
public static MvcHtmlString Angular(this HtmlHelper helper, CustomAngularComponent component)
{
// Require the resources
var _styleRegister = new ResourceRegister(helper.ViewDataContainer, _resourceManager, "Style");
var _scriptRegister = new ResourceRegister(helper.ViewDataContainer, _resourceManager, "Script");
_styleRegister.Require(component.StyleSheet).AtHead();
if (!string.IsNullOrEmpty(component.Script))
{
_scriptRegister.Require(component.Script).AtFoot();
}
// Create tag
var tag = new TagBuilder(component.Tag);
tag.MergeAttributes(component.Parameters);
return new MvcHtmlString(tag.ToString(TagRenderMode.SelfClosing));
}
}
I could use an arbitrary Shape as a helper, something like:
#Display(New.Angular(Model: new CustomAngularComponent(...)))
but a helper with strongly typed parameters feels a lot better.
This comment on another Orchard question tipped me off. As it turns out, simply injecting Work<IResourceManager> and using it directly was enough to make my setup work. Please note that this does not conform to best MVC practices, by doing this I sacrifice maintainability in favor of readability.
public static class HtmlExtensions
{
private static Work<IResourceManager> _resourceManager;
// Executed in the Activated method of an OrchardShellEvents implementation
public static void SetResourceManager(Work<IResourceManager> resourceManager)
{
_resourceManager = resourceManager;
}
public static MvcHtmlString Angular(this HtmlHelper helper, CustomAngularComponent component)
{
// Require the resources
_resourceManager.Value.Require("stylesheet", component.StyleSheet).AtHead();
if (!string.IsNullOrEmpty(component.Script))
{
_resourceManager.Value.Require("script", component.Script).AtFoot();
}
// Create tag
var tag = new TagBuilder(component.Tag);
tag.MergeAttributes(component.Parameters);
return new MvcHtmlString(tag.ToString(TagRenderMode.SelfClosing));
}
}

Approach on mocking ServiceStack service being called by another ServiceStack service

Let's say we have a situation where a service would call other services in ServiceStack.
From reading around, this is how one would call another service:
public class CompanyService : Service
{
public SetupCompanyResponse Any(SetupCompany request)
{
var employeeService = base.ResolveService<EmployeeService>();
// Do something with employeeService
var response = employeeService.Any(new SetupEmployees());
return new SetupCompanyResponse { NumOfEmployeesCreated = response.Count };
}
}
Question: How do I mock EmployeeService if I'm unit-testing CompanyService?
Easiest way I could think of is to generate an IEmployeeService interface so that it's easily mockable. However I'm not sure if base.ResolveService<T> will be able to properly resolve and auto-wire a ServiceStack service, given its interface instead, like so:
var employeeService = base.ResolveService<IEmployeeService>();
Especially when we are registering services this way (which I assume is configuring the object resolution based on concrete class, and not the interface e.g IEmployeeService)
public HelloAppHost() : base("Hello Web Services", typeof(HelloService).Assembly) { }
Update:
Apparently I'm able to somewhat achieve this simply by:
1) Registering the service interface with its implementation
public static void SetupServices(Container container)
{
container.RegisterAs<EmployeeService, IEmployeeService>();
}
2) Using the same exact code to resolve, except now I pass in the interface. The service is successfully resolved.
var employeeService = base.ResolveService<IEmployeeService>();
3) All I need to do now is to override the resolver, and the service dependency should be totally mockable.
Question: Is this also a valid approach? Why or why not?
ServiceStack's Service class resolves all its dependencies from an IResolver, defined by:
public interface IResolver
{
T TryResolve<T>();
}
This can be injected in ServiceStack's Service class in an number of ways as seen by the implementation:
public class Service : IService, IServiceBase, IDisposable
{
public static IResolver GlobalResolver { get; set; }
private IResolver resolver;
public virtual IResolver GetResolver()
{
return resolver ?? GlobalResolver;
}
public virtual Service SetResolver(IResolver resolver)
{
this.resolver = resolver;
return this;
}
public virtual T TryResolve<T>()
{
return this.GetResolver() == null
? default(T)
: this.GetResolver().TryResolve<T>();
}
...
}
Which you can use to control how Services resolve dependencies.
An easy way to unit test Services is to use a BasicAppHost as seen on the Testing wiki, i.e:
appHost = new BasicAppHost().Init();
var container = appHost.Container;
container.Register<IDbConnectionFactory>(
new OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider));
container.RegisterAutoWired<CompanyService>();
container.RegisterAutoWiredAs<StubEmployeeService, EmployeeService>();
Where StubEmployeeService is your stub implementation of EmployeeService, e.g:
public class StubEmployeeService : EmployeeService
{
public SetupEmployeesResponse Any(SetupEmployees request)
{
return new SetupEmployeesResponse { ... };
}
}
You can also register Services using any of the registration methods ServiceStack's IOC Supports if you prefer to use your own mocking library.

Setting repositories and providers

Im having a little bit of a problem trying to figure out how to do the following. My apologies if thhe following seems idiotic, just new to Castle.Windsor.
Right, In my application repositories should point to diferent dbs. They all share a abstract class (Db methods abstraction) but there is no correlation between them.
So I have something like this:
public class UserService : IUserService
{
private readonly IUserRepository _repository;
public UserService(IUserRepository repository) { _repository = repository; }
...
}
public class UserRepository : Mongo, IUserRepository
{
public UserRepository(DatabaseHosts.Users UsersHost) : base(UsersHost) { }
...
}
All configuration settings are strongly typed and so far I am calling a Installer for the Settings Service before i call Install on the rest.
My question would be: Do i have to register services and Respositories or there is something im missing?
I think, We could allow access to the DbHost property from the Service, but i rather like not.
We also have providers to external systems which might need some sort of initialization.
So far i have soemthing like this:
public class ServicesInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Component.For<IUserService>()
.ImplementedBy<IUserService>()
.LifeStyle.Singleton);
}
}
Ta
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Component.For<IUserService>()
.ImplementedBy<UserService>()
.LifeStyle.Singleton);
}
you have to register the concrete service "UserService" to the interface in order to allow the container to determine which concrete to resolve.

looking for a proper way to implement my generic factory

I'm struggling with implementing a factory object. Here's the context :
I've in a project a custom store. In order to read/write records, I've written this code in a POCO model/separated repository:
public class Id { /* skip for clarity*/} // My custom ID representation
public interface IId
{
Id Id { get; set; }
}
public interface IGenericRepository<T> where T : IId
{
T Get(Id objectID);
void Save(T #object);
}
public interface IContext
{
TRepository GetRepository<T, TRepository>()
where TRepository : IGenericRepository<T>
where T:IId;
IGenericRepository<T> GetRepository<T>()
where T:IId;
}
My IContext interface defines two kind of repositories.
The former is for standard objects with only get/save methods, the later allows me to define specifics methods for specific kind of objects. For example :
public interface IWebServiceLogRepository : IGenericRepository<WebServiceLog>
{
ICollection<WebServiceLog> GetOpenLogs(Id objectID);
}
And it the consuming code I can do one of this :
MyContext.GetRepository<Customer>().Get(myID); --> standard get
MyContext.GetRepository<WebServiceLog, IWebServiceLogRepository>().GetOpenLogs(myID); --> specific operation
Because most of objects repository are limited to get and save operations, I've written a generic repository :
public class BaseRepository<T> : IGenericRepository<T>
where T : IId, new()
{
public virtual T Get(Id objectID){ /* provider specific */ }
public void Save(T #object) { /* provider specific */ }
}
and, for custom ones, I simply inherits the base repository :
internal class WebServiceLogRepository: BaseRepository<WebServiceLog>, IWebServiceLogRepository
{
public ICollection<WebServiceLog> GetByOpenLogsByRecordID(Id objectID)
{
/* provider specific */
}
}
Everything above is ok (at least I think it's ok). I'm now struggling to implement the MyContext class. I'm using MEF in my project for other purposes. But because MEF doesn't support (yet) generic exports, I did not find a way to reach my goal.
My context class is looking like by now :
[Export(typeof(IContext))]
public class UpdateContext : IContext
{
private System.Collections.Generic.Dictionary<Type, object> m_Implementations;
public UpdateContext()
{
m_Implementations = new System.Collections.Generic.Dictionary<Type, object>();
}
public TRepository GetRepository<T, TRepository>()
where T : IId
where TRepository : IGenericRepository<T>
{
var tType = typeof(T);
if (!m_Implementations.ContainsKey(tType))
{
/* this code is neither working nor elegant for me */
var resultType = AppDomain.CurrentDomain.GetAssemblies().SelectMany(
(a) => a.GetTypes()
).Where((t)=>t.GetInterfaces().Contains(typeof(TRepository))).Single();
var result = (TRepository)resultType.InvokeMember("new", System.Reflection.BindingFlags.CreateInstance, null, null, new object[] { this });
m_Implementations.Add(tType, result);
}
return (TRepository)m_Implementations[tType];
}
public IGenericRepository<T> GetRepository<T>() where T : IId
{
return GetRepository<T, IGenericRepository<T>>();
}
}
I'd appreciate a bit of help to unpuzzle my mind with this quite common scenario
Not sure if I've understood you correctly, but I think you're perhaps over complicating things. To begin with, make sure you've designed your code independent of any factory or Dependency Injection framework or composition framework.
For starters lets look at what you want your calling code to look like, this is what you said:
MyContext.GetRepository<Customer>().Get(myID); --> standard get
MyContext.GetRepository<WebServiceLog, IWebServiceLogRepository>().GetOpenLogs(myID);
You don't have to agree with my naming choices below, but it indicates what I undertand from your code, you can tell me if I'm wrong. Now, I feel like the calling would be simpler like this:
RepositoryFactory.New<IRepository<Customer>>().Get(myId);
RepositoryFactory.New<IWebServiceLogRepository>().GetOpenLogs(myId);
Line 1:
Because the type here is IRepository it's clear what the return type is, and what the T type is for the base IRepository.
Line 2:
The return type here from the factory is IWebServiceLogRepository. Here you don'y need to specify the entity type, your interface logically already implements IRepository. There's no need to specify this again.
So your interface for these would look like this:
public interface IRepository<T>
{
T Get(object Id);
T Save(T object);
}
public interface IWebServiceLogRepository: IRepository<WebServiceLog>
{
List<WebServiceLog> GetOpenLogs(object Id);
}
Now I think the implementations and factory code for this would be simpler as the factory only has to know about a single type. On line 1 the type is IRepository, and in line 2, IWebServiceLogRepository.
Try that, and try rewriting your code to simply find classes that implement those types and instantiating them.
Lastly, in terms of MEF, you could carry on using that, but Castle Windsor would really make things much simpler for you, as it lets you concentrate on your architecture and code design, and its very very simple to use. You only ever reference Castle in your app startup code. The rest of your code is simply designed using the Dependency Injection pattern, which is framework agnostic.
If some of this isn't clear, let me know if you'd like me to update this answer with the implementation code of your repositories too.
UPDATE
and here's the code which resolves the implementations. You were making it a bit harder for yourself by not using the Activator class.
If you use Activator and use only one Generic parameter as I've done in the method below, you should be ok. Note the code's a bit rough but you get the idea:
public static T GetThing<T>()
{
List<Type> assemblyTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes()).ToList();
Type interfaceType = typeof(T);
if(interfaceType.IsGenericType)
{
var gens = interfaceType.GetGenericArguments();
List<Type> narrowed = assemblyTypes.Where(p => p.IsGenericType && !p.IsInterface).ToList();
var implementations = new List<Type>();
narrowed.ForEach(t=>
{
try
{
var imp = t.MakeGenericType(gens);
if(interfaceType.IsAssignableFrom(imp))
{
implementations.Add(imp);
}
}catch
{
}
});
return (T)Activator.CreateInstance(implementations.First());
}
else
{
List<Type> implementations = assemblyTypes.Where(p => interfaceType.IsAssignableFrom(p) && !p.IsInterface).ToList();
return (T)Activator.CreateInstance(implementations.First());
}
}

Is it ok to set Datacontext as a property in repository?

Is there any potential problem in setting datacontext as property like this:
repository
public Repository()
{
public DataContext dc {get;set;}
public GetOrders(int id)
{ ...from dc.Orders...}
}
service layer:
public GetNewOrders()
{
....
Repository rep=new Repository();
using {DataContext dc=new DataContext())
{
rep.dc=dc;
rep.GetOrders(id);
}
}
From what I have read, using the DataContext "for more than one business conversation is usually the wrong thing to do." Scroll down to the Why Is This Important? section for the quote. Due to caching and other factors, you should consider your DataContext stale immediately. From that, it is safe to say you don't want to keep the DataContext as a property that is reused by all your methods. Using Eric Duncan's suggestion, you will want to pass in some kind of DataContext factory to get a new context for each query.
For a discussion focused on the DataContext, the APress Pro LINQ book has an entire chapter on the DataContext, the very last page of which also advises you to "consider the DataContext stale immediately."
In DDD, you're missing the bigger picture here by referencing the concret classes. You are not interfacing between the Repository and "Services layer" by best practices. If you must have DataContext injected into the Repository, I would recommend refactoring to:
public interface IRepository
{
IList<Orders> GetNewOrders();
}
public Repository : IRepository
{
private IDataContext _dataContext;
public Repository(IDataContext dataContext)
{
_dataContext = dataContext;
}
public IList<Orders> GetNewOrders()
{
// perform your actions on _dataContext here
}
}
The better solution would be to let the Repository handle the DataContext on its own - keeping the seperation of concert valid by masking the underlying requirements:
public interface IRepository
{
IList<Orders> GetNewOrders();
}
public Repository : IRepository
{
private IDataContext _dataContext;
public Repository(String connectionString)
{
_dataContext = new DataContext(connectionString);
}
public IList<Orders> GetNewOrders()
{
// perform your actions on _dataContext here
}
}
If you must keep control of the DataContext (or another class) yourself (perhaps you want to keep a static reference around, or change settings based on an WebRequest, etc), you you will need to use a "Factory".
The factory would look something like this:
public static class DataContextFactory
{
public static IDataContext GetInstance()
{
// return either a static instance,
// or threaded instance, a GlobalContext instance
// or whatever your preference is here
//
}
}
That way, you have full control over how the instance of DataContext is controlled outside and away from your "Services" layer. So, you would use this DataContextFactory like the following:
public interface IRepository
{
IList<Orders> GetNewOrders();
}
public Repository : IRepository
{
public IList<Orders> GetNewOrders()
{
using (var dataContext = DataContextFactory.GetInstance())
{
// dataContext is now your IDataContext to work with
}
}
}
"How to access the IRepository?" you may ask?
Your services layer would do something like:
public void GetNewOrdersForServices()
{
// Not recommended!
// IRepository repo = new Repository()
//
// The following is recommended instead; because, it removes the
// the Concret reference from your Services layer completely!
//
IRepository repo = ServiceLocator.InstanceOf<IRepository>();
IList myList = repo.GetNewOrders();
}
Or, you would inject it into the constructor of your service using your favorite flavor of Inversion of Control container like so:
public class OrderService
{
private IRepository _repo;
public OrderService(IRepository repo)
{
_repo = repo;
}
public void GetNewOrdersForServices()
{
IList myList = _repo.GetNewOrders();
}
If you are not fimilar with the service locator concepts, check out Castle Windsor as it Encapsulates just about all your needs.

Resources