Sometime ago I removed a chain of responsibility in a web site that I'am working on.
The chain would call a method to generate a dynamic form for the website. Every object called would either return their form or "pass the ball" to the next object to retrieve the form.
The website has around 300+ classes with this logic, no big deal in terms of performance but I found it horrible to see it and debugging it.
So I decided to remove the chain call and just replaced it with reflection, I know what object I have to call by a unique static "name" (the same name was used in the chain to check if the object has to load the form or "pass the ball") of the class and by foreaching all the objects in a list I'll check that name to be sure to call the correct class/method.
I know that reflection is supposed to be slower in terms of performance but after some tests I can't see any sustantial difference and since the code is much cleaner it's easier to understand and debug.
So my question is:
Is this a correct approach or is there any better pattern to use in a case like this ?
I feel like I use reflection more then I should when I'am coding and I don't know if it is always the better option.
This in 1 class:
foreach (TemplateHandler t in objectList)
{
if (t.GetType().GetProperty("serviceCode") != null)
{
if (t.GetType().GetProperty("serviceCode").GetValue(t).ToString() == serviceCodeToCallFromParam)
{
return t.GetTemplateParam(serviceCodeToCallFromParam/*, ...other params...*/);
}
}
}
over this in 300+ class:
public override List<Form> GetTemplateParam(string serviceCode)
{
if (serviceCode == ClassServiceCode)
{
// long form logic build.
//..
}
else
{
if (successor != null)
form = successor.GetTemplateParam(serviceCode);
}
return form;
}
Reflection solution looks better if I have to choose from those two. Passing ball for 300 times looks meaningless.
But, as you noted, the performance might be the issue. If you already know the class to call for getting work done, why not implement something like Builder or Factory pattern to create an instance of appropriate class and get the work done through.
Even simpler is the switch-case structure. Put and creation code in switch-case and use the resultant object to do work.
Edit 1:
public T CreateTemplate<T>() where T : ITemplate
{
ITemplate template = null;
if(typeof(T) == typeof(Type1Template))
template = new Type1Template(....);
else if(typeof(T) == typeof(Type2Template))
template = new Type2Template(....);
else
throw new TemplateException("Template type is not configured.");
return (T)template;
}
Edit 2
See if something like below helps then:
public T CreateTemplate<T>()
{
ITemplate template = (T)Activator.CreateInstance(typeof(T));
return template;
}
Related
A brainteaser for you!
I am developing a modular system, in such a way that module A could need module B and module B could also need module A. But if module B is disabled, it will simply not execute that code and do nothing / return null.
A little bit more into perspective:
Let's say InvoiceBusinessLogic is within module "Core". We also have a "Ecommerce" module which has a OrderBusinessLogic. The InvoiceBusinessLogic could then look like this:
public class InvoiceBusinessLogic : IInvoiceBusinessLogic
{
private readonly IOrderBusinessLogic _orderBusinessLogic;
public InvoiceBusinessLogic(IOrderBusinessLogic orderBusinessLogic)
{
_orderBusinessLogic = orderBusinessLogic;
}
public void UpdateInvoicePaymentStatus(InvoiceModel invoice)
{
_orderBusinessLogic.UpdateOrderStatus(invoice.OrderId);
}
}
So what I want is: When the module "Ecommerce" is enabled, it would actually do something at the OrderBusinessLogic. When not, it would simply not do anything. In this example it returns nothing so it can simply do nothing, in other examples where something would be returned, it would return null.
Notes:
As you can probably tell, I am using Dependency Injection, it is a ASP.NET Core application so the IServiceCollection takes care of defining the implementations.
Simply not defining the implementation for IOrderBusinessLogic will cause a runtime issue, logically.
From a lot of research done, I do not want to make calls to the container within my domain / logic of the app. Don't call the DI Container, it'll call you
These kind of interactions between modules are kept to a minimum, preferably done within the controller, but sometimes you cannot get around it (and also in the controller I would then need a way to inject them and use them or not).
So there are 3 options that I figured out so far:
I never make calls from module "Core" to module "Ecommerce", in theory this sounds the best way, but in practice it's more complicated for advanced scenarios. Not an option
I could create a lot of fake implementations, depending on the configuration decide on which one to implement. But that would of course result in double code and I would constantly have to update the fake class when a new method is introduced. So not perfectly.
I can build up a fake implementation by using reflection and ExpandoObject, and just do nothing or return null when the particular method is called.
And the last option is what I am now after:
private static void SetupEcommerceLogic(IServiceCollection services, bool enabled)
{
if (enabled)
{
services.AddTransient<IOrderBusinessLogic, OrderBusinessLogic>();
return;
}
dynamic expendo = new ExpandoObject();
IOrderBusinessLogic fakeBusinessLogic = Impromptu.ActLike(expendo);
services.AddTransient<IOrderBusinessLogic>(x => fakeBusinessLogic);
}
By using Impromptu Interface, I am able to successfully create a fake implementation. But what I now need to solve is that the dynamic object also contains all the methods (mostly properties not needed), but those ones are easy to add. So currently I am able to run the code and get up until the point it will call the OrderBusinessLogic, then it will, logically, throw an exception that the method does not exist.
By using reflection, I can iterate over all the methods within the interface, but how do I add them to the dynamic object?
dynamic expendo = new ExpandoObject();
var dictionary = (IDictionary<string, object>)expendo;
var methods = typeof(IOrderBusinessLogic).GetMethods(BindingFlags.Public);
foreach (MethodInfo method in methods)
{
var parameters = method.GetParameters();
//insert magic here
}
Note: For now directly calling typeof(IOrderBusinessLogic), but later I would iterate over all the interfaces within a certain assembly.
Impromptu has an example as follows:
expando.Meth1 = Return<bool>.Arguments<int>(it => it > 5);
But of course I want this to be dynamic so how do I dynamically insert the return type and the parameters.
I do understand that a interface acts like a contract, and that contract should be followed, I also understand that this is an anti-pattern, but extensive research and negotiations have been done prior to reaching this point, for the result system we want, we think this is the best option, just a little missing piece :).
I have looked at this question, I am not really planning on leaving .dll's out, because most likely I would not be able to have any form of IOrderBusinessLogic usable within InvoiceBusinessLogic.
I have looked at this question, but I did not really understand how TypeBuilder could be used in my scenario
I have also looked into Mocking the interfaces, but mostly you would then need to define the 'mocking implementation' for each method that you want to change, correct me if I am wrong.
Even tough the third approach (with ExpandoObject) looks like a holy grail, I foster you to not follow this path for the following reasons:
What guarantees you that this fancy logic will be error-free now and at every time in the future ? (think: in 1 year you add a property in IOrderBusinessLogic)
What are the consequences if not ? Maybe an unexpected message will pop to the user or cause some strange "a priori unrelated" behavior
I would definitely go down the second option (fake implementation, also called Null-Object) even though, yes it will require to write some boilerplate code but ey this would offer you a compile-time guarantee that nothing unexpected will happen at rutime !
So my advice would be to do something like this:
private static void SetupEcommerceLogic(IServiceCollection services, bool enabled)
{
if (enabled)
{
services.AddTransient<IOrderBusinessLogic, OrderBusinessLogic>();
}
else
{
services.AddTransient<IOrderBusinessLogic, EmptyOrderBusinessLogic>();
}
}
For as long as there is no other answer for the solution I am looking for, I came up with the following extension:
using ImpromptuInterface.Build;
public static TInterface IsModuleEnabled<TInterface>(this TInterface obj) where TInterface : class
{
if (obj is ActLikeProxy)
{
return default(TInterface);//returns null
}
return obj;
}
And then use it like:
public void UpdateInvoicePaymentStatus(InvoiceModel invoice)
{
_orderBusinessLogic.IsModuleEnabled()?.UpdateOrderStatus(invoice.OrderId);
//just example stuff
int? orderId = _orderBusinessLogic.IsModuleEnabled()?.GetOrderIdForInvoiceId(invoice.InvoiceId);
}
And actually it has the advantage that it is clear (in the code) that the return type can be null or the method won't be called when the module is disabled. The only thing that should be documented carefully, or in another way enforced, that is has to be clear which classes do not belong to the current module. The only thing I could think of right now is by not including the using automatically, but use the full namespace or add summaries to the included _orderBusinessLogic, so when someone is using it, it is clear this belongs to another module, and a null check should be performed.
For those that are interested, here is the code to correctly add all fake implementations:
private static void SetupEcommerceLogic(IServiceCollection services, bool enabled)
{
if (enabled)
{
services.AddTransient<IOrderBusinessLogic, OrderBusinessLogic>();
return;
}
//just pick one interface in the correct assembly.
var types = Assembly.GetAssembly(typeof(IOrderBusinessLogic)).GetExportedTypes();
AddFakeImplementations(services, types);
}
using ImpromptuInterface;
private static void AddFakeImplementations(IServiceCollection services, Type[] types)
{
//filtering on public interfaces and my folder structure / naming convention
types = types.Where(x =>
x.IsInterface && x.IsPublic &&
(x.Namespace.Contains("BusinessLogic") || x.Namespace.Contains("Repositories"))).ToArray();
foreach (Type type in types)
{
dynamic expendo = new ExpandoObject();
var fakeImplementation = Impromptu.DynamicActLike(expendo, type);
services.AddTransient(type, x => fakeImplementation);
}
}
I am currently in the process of adding CodeContracts to my existing code base.
One thing that proves difficult is the usage of entities that are hydrated by NHibernate.
Assume this simple class:
public class Post
{
private Blog _blog;
[Obsolete("Required by NHibernate")]
protected Post() { }
public Post(Blog blog)
{
Contract.Requires(blog != null);
_blog = blog;
}
public Blog Blog
{
get
{
Contract.Ensures(Contract.Result<Blog>() != null);
return _blog;
}
set
{
Contract.Requires(value != null);
_blog = value;
}
}
[ContractInvariantMethod]
private void Invariants()
{
Contract.Invariant(_blog != null);
}
}
This class tries to protect the invariant _blog != null. However, it currently fails, because I easily could create an instance of Post by deriving from it and using the protected constructor. In that case _blog would be null.
I am trying to change my code-base in a way that the invariants are indeed protected.
The protected constructor is at first sight needed by NHibernate to be able to create new instances, but there is a way around this requirement.
That approach basically uses FormatterServices.GetUninitializedObject. The important point is, that this method doesn't run any constructors.
I could use this approach and it would allow me to get rid of the protected constructor. The static checker of CodeContracts would now be happy and not report any more violations, but as soon as NHibernate tries to hydrate such entities it will generate "invariant failed" exceptions, because it tries to set one property after the other and every property setter executes code that verifies the invariants.
So, to make all this work, I will have to ensure that the entities are instantiated via their public constructor.
But how would I do this?
Daniel, if I'm not mistaken (it's been a while since I worked with NH) you can have a private constructor and he still should be fine creating your object.
Aside from that, why do you need to be a 100% sure? Is it a requirement in some way or you are just trying to covering all the bases?
I ask that because depending on the requirement we could come with another way of achieving it.
What you COULD do right now to provide that extra protection is wire up an IInterceptor class to make sure that after the load your class is still valid.
I guess that the bottom line is if someone want's to mess up with your domain and classes they WILL do it no matter what you do. The effort to prevent all that stuff doesn't pay off in most cases.
Edit after clarification
If you use your objects to write to the database and you contracts are working you can safely assume that the data will be written correctly and therefore loaded correctly if no one tampers with the database.
If you do change the database manually you should either stop doing it and use your domain to do that (that's where the validation logic is) or test the database changing process.
Still, if you really need that you can still hook up a IInterceptor that will validate your entity after the load, but I don't think you fix a water flooding coming from the street by making sure your house pipe is fine.
Based on the discussion with tucaz, I came up with the following, in its core rather simple solution:
The heart of this solution is the class NHibernateActivator. It has two important purposes:
Create an instance of an object without invoking its constructors. It uses FormatterServices.GetUninitializedObject for this.
Prevent the triggering of "invariant failed" exceptions while NHibernate hydrates the instance. This is a two-step task: Disable invariant checking before NHibernate starts hydrating and re-enable invariant checking after NHibernate is done.
The first part can be performed directly after the instance has been created.
The second part is using the interface IPostLoadEventListener.
The class itself is pretty simple:
public class NHibernateActivator : INHibernateActivator, IPostLoadEventListener
{
public bool CanInstantiate(Type type)
{
return !type.IsAbstract && !type.IsInterface &&
!type.IsGenericTypeDefinition && !type.IsSealed;
}
public object Instantiate(Type type)
{
var instance = FormatterServices.GetUninitializedObject(type);
instance.DisableInvariantEvaluation();
return instance;
}
public void OnPostLoad(PostLoadEvent #event)
{
if (#event != null && #event.Entity != null)
#event.Entity.EnableInvariantEvaluation(true);
}
}
DisableInvariantEvaluation and EnableInvariantEvaluation are currently extension methods that use reflection to set a protected field. This field prevents invariants from being checked. Furthermore EnableInvariantEvaluation will execute the method that checks the invariants if it gets passed true:
public static class CodeContractsExtensions
{
public static void DisableInvariantEvaluation(this object entity)
{
var evaluatingInvariantField = entity.GetType()
.GetField(
"$evaluatingInvariant$",
BindingFlags.NonPublic |
BindingFlags.Instance);
if (evaluatingInvariantField == null)
return;
evaluatingInvariantField.SetValue(entity, true);
}
public static void EnableInvariantEvaluation(this object entity,
bool evaluateNow)
{
var evaluatingInvariantField = entity.GetType()
.GetField(
"$evaluatingInvariant$",
BindingFlags.NonPublic |
BindingFlags.Instance);
if (evaluatingInvariantField == null)
return;
evaluatingInvariantField.SetValue(entity, false);
if (!evaluateNow)
return;
var invariantMethod = entity.GetType()
.GetMethod("$InvariantMethod$",
BindingFlags.NonPublic |
BindingFlags.Instance);
if (invariantMethod == null)
return;
invariantMethod.Invoke(entity, new object[0]);
}
}
The rest is NHibernate plumbing:
We need to implement an interceptor that uses our activator.
We need to implement an reflection optimizer that returns our implementation of IInstantiationOptimizer. This implementation in turn again uses our activator.
We need to implement a proxy factory that uses our activator.
We need to implement IProxyFactoryFactory to return our custom proxy factory.
We need to create a custom proxy validator that doesn't care whether the type has a default constructor.
We need to implement a bytecode provider that returns our reflection optimizer and proxy-factory factory.
NHibernateActivator needs to be registered as a listener using config.AppendListeners(ListenerType.PostLoad, ...); in ExposeConfiguration of Fluent NHibernate.
Our custom bytecode provider needs to be registered using Environment.BytecodeProvider.
Our custom interceptor needs to be registered using config.Interceptor = ...;.
I will update this answer when I had the chance to create a coherent package out of all this and put it on github.
Furthermore, I want to get rid of the reflection and create a proxy type instead that can directly access the protected CodeContract members.
For reference, the following blog posts where helpful in implementing the several NHibernate interfaces:
http://weblogs.asp.net/ricardoperes/archive/2012/06/19/implementing-an-interceptor-using-nhibernate-s-built-in-dynamic-proxy-generator.aspx
http://kozmic.net/2011/03/20/working-with-nhibernate-without-default-constructors/
Unfortunately, this currently fails for entities with composite keys, because the reflection optimizer is not used for them. This is actually a bug in NHibernate and I reported it here.
Let's say I have a long established repository like this:
interface IDonutRepository
{
public IEnumerable<Donut> GetDonuts();
}
It's been around for ages, and the GetDonuts method does what it says. Then one day I need to add a new screen that shows all the donuts in the database, and it turns out that the method has a hidden feature - it filters out all donuts where stale = true. But on my new screen, I want to show all of them, even the stale ones! What is the best approach here?
Assuming that this method is used all over the place, and the default behaviour needs to stay the same, is it best to add a new method called GetAllDonuts that doesn't do the filtering, or should I just add a onlyFresh parameter onto the GetDonuts method?
I'm guessing its just down to judgement, but I'm wondering if there are any more informed answers out there?
I would overload the method creating a new overload that takes the showStale parameter and then modify the old method to use the new overload passing false for the parameter value.
The interface would look like:
interface IDonutRepository
{
public IEnumerable<Donut> GetDonuts();
public IEnumerable<Donut> GetDonuts(bool showStale);
}
Or if you're using .NET 4.0, you can use an optional parameter:
interface IDonutRepository
{
public IEnumerable<Donut> GetDonuts(bool showStale = false);
}
Why not use an optional parameter? This way you don't break existing code:
interface IDonutRepository
{
public IEnumerable<Donut> GetDonuts(bool onlyFresh);
}
Implementation:
public IEnumerable<Donut> GetDonuts(bool onlyFresh = false)
{
if (onlyFresh)
// do stuff
else
// do other stuff
}
This really comes down to personal preference, to some extent...
If you have the ability to change the API, I would (personally) rename the current method in a way that makes it obvious that it is not returning all Donut instances. My expectation would be that a repository's GetDonuts method would get all of the donuts. This could be doing via a parameter, or a different name, at your discretion.
That being said, a method overload taking the extra parameter is probably the best option moving forward, if keeping compatibility is critical. (This depends a lot on who and where this API is used...)
Depending on the circumstancs, one might consider introducing a property for accessing the donuts.
interface IDonutRepository
{
IEnumerable<Donut> Donuts { get; }
.. or ..
IQueryable<Donut> Donuts { get; }
}
It's fairly easy to implement this interface if you're using a Linq-savvy ORM like Entity Framework or NHibernate.
The old GetDonuts method could be renamed GetFreshDonuts(), or you could refactor calls to it into the form:
repository.Donuts.Where(x => !x.Stale)
One of the growing trends in software
design is separating interface from
implementation. The principle is about
separating modules into public and
private parts so that you can change
the private part without coordinating
with other modules. However, there is
a further distinction—the one between
public and published interfaces. This
distinction is important because it
affects how you work with the
interface.
http://www.martinfowler.com/ieeeSoftware/published.pdf
We are working on improving our DAL which is written in LINQ that talks to the MS SQL database. Our goal is to achieve good re-usability with as little code as possible.
LINQ generated files are making a use of generics and reflection to map LINQ generated classes to the SQL objects (tables and views in our case).
Please see the example of the existing accessor. This method resides in the partial class that contains custom constructors, accessors and mutators:
public clsDVD getDVD(int dvdId)
{
try
{
using (DataContext dvdDC = new DataContext(ConnectionStringManager.getLiveConnStr()))
{
// Deferred loading
dvdDC.DeferredLoadingEnabled = false;
var tDVD = dvdDC.GetTable<DVD>();
return (from t in tDVD
// Filter on DVD Id
where t.DVDId == (dvdId)
select t).Single();
}
catch (Exception e)
{
Logger.Log("Can't get requested DVD.", e);
throw;
}
}
I believe that this is very easy to maintain, since the most of the work is done after var tDVD
It has been suggested not to declare tDVD at all and use dataContext.TableName, but behind the scenes it still calls GetTable<>.
The only way I can see of improving this is breaking this one partial class into 4 (CRUD) partial classes. E.g.
clsDVD_Select, clsDVD_Update, clsDVD_Insert, clsDVD_Delete
In this case each class will represent a set of behaviours.
The idea that we are discussing is to see whether it's possible to use generics on top of LINQ generics.
For example, instead of having the partial classes, we would figure out the properties of the class on the go by using reflection against the SQL database. My first concern here is performance impact. How significant will it be.
Instead of ClsDVD.getDVD(1231) we'd have something on the lines of: GenericDC.Select<DVD>(1231)
.Select method would figure out the primary key and run a select query on that table. I'm struggling to understand how can this work. Lets say we can get this to work for the simple select, i.e. select with a filter on primary key, but what is going to happen when we start doing complex joins and group by selects. What happens when we want to have multiple selects per DVD class?
My final concern is to do with good practices. I have been told before that it's good to have consistant code. For example, If I decide to use datatables , than I should stick to datatables throughout the project. It's a bad idea to have half of the project with datatables and another half with user defined classes. Do you agree on this?
I'm in a position where I think that existing implementation is quite good but maybe I'm missing out something very obvious and there is a much easier, more OO way of achieving the same results?
Thank you
Here is one way to make this situation a little more generic. Rince and repeat for the other CRUD opperations. For some sitiations the performance may be unacceptable. In those cases I would restructure that part of the program to call a non generic version.
public T GetSingleItem(Func<T,bool> idSelector ) where T : ??? // forgot what type it needs to be off the top of my head
{
try
{
using (DataContext context = new DataContext(ConnectionStringManager.getLiveConnStr()))
{
context.DeferredLoadingEnabled = false;
return context.GetTable<T>().Single( item => idSelector( item );
}
}
catch (Exception e)
{
Logger.Log("Can't get requested item.", e);
throw;
}
}
This would be how you woudl have to get the item. Not quite as elegant becase you have to tell the generic function which column you are going to be using.
GenericDC.GetSingleItem<DVD>( dvd => dvd.ID == 1231 )
To make this even more generic that limiting it to a single item with an ID...
public IEnumerable<T> GetItems(Func<T,bool> selectFunction ) where T : ??? // forgot what type it needs to be off the top of my head
{
try
{
using (DataContext context = new DataContext(ConnectionStringManager.getLiveConnStr()))
{
context.DeferredLoadingEnabled = false;
return context.GetTable<T>().Select( item => selectFunction( item );
}
}
catch (Exception e)
{
Logger.Log("Can't get requested item.", e);
throw;
}
}
Then you can call it like:
GenericDC.GetItems<DVD>( dvd => dvd.Title == "Title" && dvd.Cast.Contains( "Actor" ) );
Another possible solution would be to create a custom code generator that could you could modify in one place and create the similar routines for all other types. This would probably be a good solution if you are running into performace problems. You would want to limit the changes to the template piece of code that you use.
This question is related to a previous post of mine Here. Basically, I want to inject a DAO into an entity i.e.
public class User
{
IUserDAO userDAO;
public User()
{
userDAO = IoCContainer.Resolve<IUserDAO>;
}
public User(IUserDAO userDAO)
{
this.userDAO = userDAO;
}
//Wrapped DAO methods i.e
public User Save()
{
return userDAO.Save(this);
}
}
Here if I had a custom methods in my DAO then I basically have to wrap them in the entity object. So if I had a IUserDAO.Register() I would then have to create a User.Register() method to wrap it.
What would be better is to create a proxy object where the methods from the DAO are dynamically assign to the User object. So I may have something that looks like this:
var User = DAOProxyService.Create(new User());
User.Save();
This would mean that I can keep the User entity as a pretty dumb class suitable for data transfer over the wire, but also magically give it a bunch of DAO methods.
This is very much out of my confort zone though, and I wondered what I would need to accomplish this? Could I use Castles Dynamic proxy? Also would the C# compiler be able to cope with this and know about the dynamically added methods?
Feel free to let me know if this is nonsense.
EDIT:
What we need to do it somehow declare DAOProxyService.Create() as returning a User object -- at compile time. This can be done with generics.
This isnt quite true, what I want to return isn't a User object but a User object with dynamically added UserDAO methods. As this class isn't defnied anywhere the compiler will not know what to make of it.
What I am essentially returning is a new object that looks like: User : IUserDAO, so I guess I could cast as required. But this seems messy.
Looks like what I am looking for is similar to this: Mixins
I was initially going to say what you ask cannot work. But with some tweaking, we might be able to get it to work.
var is just a compiler feature. When you say.
var x = GetSomeValue();
the compiler says "'GetSomeValue' is defined as returning a string, so the programmer must of meant to write 'string x = GetSomeValue();'". Note that the compiler says this; this change is done at compile time.
You want to define a class (DAOProxyService) which essentially returns an Object. This will work, but "var User" would be the same as "Object user".
What we need to do it somehow declare DAOProxyService.Create() as returning a User object -- at compile time. This can be done with generics:
class DAOProxyService
{
static DAOProxyService<T> Create<T>(T obj) { ......}
}
It's not entirely automatic, but you might consider using a variation of Oleg Sych's method for generating decorator classes. Whenever IUserDAO changes (new method, etc) just regenerate the file. Better than maintaining it manually :-)
http://www.olegsych.com/2007/12/how-to-use-t4-to-generate-decorator-classes/