C# Domain Specific Implementations: Unity and Generics - c#

I have created components containing domain specific information in my application e.g. ImportManager, ExportManager etc
I'd like each component to operate as an isolated unit but I'm coming a little undone by my use of generics - when used with dependency inject (unity).
I have the following base object defined in a library.
public class ImportManager : IImportManager
{
[Dependency]
public IImportSettings Settings {get;set;}
}
The idea here being that I define a base class that implements standard functionality.
I then create a client-specific implementation which changes the standard behaviour slightly. This class has its own implementation and settings implemented in a different assembly as follows:
public class CustomImportManager : ImportManager, ICustomImportManager
{
}
The difference with this implementation is that I'd like to load ICustomSettings into the CustomImportManager - not ISettings.
I could just register the dependency in my bootstrapper and it would load fine but then I would have to cast the settings object every time I use it in CustomImportManager.
Alternatively, I could define a generic parameter on IImportManager:
public interface IImportManager<TSettings> where TSettings: ISettings
{
[Dependency]
public TSettings Settings {get; set}
}
Unfortunately this will require me to add the generic parameter to every class that defines this interface as a property leading to classes having masses of generic parameters.
In the example below, the facade could potentially implement 10+ components depending on its requirements meaning I'd have to define a TObject for every component - also making it very difficult to use itself.
public class Facade
{
[Dependency] IImportManager ImportManager {get; set; }
}
Does anybody have any ideas on how I may get around this?
Thanks in advance

Related

MissingMethodException after extracting base interface

I split an interface, inside a Nuget package library, into a simpler base interface (without one property from the original), and made the original derive from the new base interface.
Instantiation in consuming applications happens through Managed Extensibility Framework (MEF), using property injection with [Import] attributes, and implementations with [Export(typeof(IFooConfigurations))]
This shouldn't be a breaking change, for applications using the old interface and implementation. But in some cases, different libraries are loaded, which use old interface versions and implementations. This results in MissingMethodExceptions at runtime, saying a method or property (get method) does not exist - such as the Configurations list property in the example.
Old:
public interface IFooConfigurations
{
int ConfigurationsIdentifier { get; }
IReadOnlyList<Configuration> Configurations { get; }
}
New:
public interface IBaseFooConfigurations
{
// without the ConfigurationsIdentifier
IReadOnlyList<Configuration> Configurations { get; }
}
public interface IFooConfigurations : IBaseFooConfigurations
{
int ConfigurationsIdentifier { get; }
// Configurations inherited from IBaseFooConfigurations
}
Implementation (not changed)
[Export(typeof(IFooConfigurations)]
public class FooConfigurations : IFooConfigurations
{
// implementations of ConfigurationsIdentifier and Configurations
}
Usage (not changed), resolved through MEF
public class FooApplicationClass
{
[Import]
private IFooConfigurations ConfigurationsOwner { get; set; }
}
It is quite hard to track this error and find possible causes, because it doesn't occur in the usual development environment.
Could it be a solution, to replicate all the old properties and methods, which are now in the base interface, in the new version of the IFooConfigurations interface, with the new keyword, while still deriving from the new IBaseFooConfigurations?
Possible solution?
public interface IFooConfigurations : IBaseFooConfigurations
{
int ConfigurationsIdentifier { get; }
new IReadOnlyList<Configuration> Configurations { get; }
}
EDIT: It seems like keeping the members of the original interface, hiding the inherited ones with the "new" keyword, solved the problem. Probably, older applications and libraries, working with the original interface, couldn't resolve the inherited members as parts of the original interface. However, explicit implementations and mocks can potentially be troublesome with this. There is still testing to be done.
Interface members, inherited from another interface, are not equivalent to members, which are defined in the interface itself. Therefore, moving members to a base interface and inheriting from it, is a breaking change. To be downward compatible, the members of the interface must also be defined in itself, as "new" (in C#).
I confirmed this with a simple test program, referencing different builds of DLLs with the original single interface, the split-up and another with the split-up and duplicate "new" members. So it is not an issue of MEF.
Unfortunately, this problem only occurs at runtime, after a release of the nuget package has already been built.

Unintended method exposure using inheritance with a generics typed class

I did my best with the title. What I am trying to accomplish is tiered modularity with dependency injection. Whether or not this design pattern is good is a question for another forum.
Because I am using dependency injection, I have interface/implementation pairs. This is the top-level inteface:
public interface IConfiguration<T> where T : ConfigData
{
T GetConfig();
}
Where ConfigData is a simple class that exposes get/set properties like LogLevel and Environment.
There is a base implementation of the interface:
public abstract class ConfigurationBase<T> : IConfiguration
{
protected ConfigData Config { get; set; }
public T GetConfig()
{
return Config as T;
}
}
Now for the dependency injection part of this! I have several interface/implementation pairs that hierarchically inherit from one another. Furthermore, their protected Config property also exposes more properties in each subsequent child class. Here are my interface/implementation signatures:
public interface IGeneralConfiguration : IConfiguration<GeneralConfigData>
public class GeneralConfiguration : ConfigurationBase<GeneralConfigData>, IGeneralConfiguration
public interface ILoginConfiguration : IConfiguration<LoginConfigData>, IGeneralConfiguration
public class LoginConfiguration : ConfigurationBase<LoginConfigData>, ILoginConfiguration
public interface IAppConfiguration : IConfiguration<AppConfigData>, ILoginConfiguration
public class AppConfiguration : ConfigurationBase<AppConfigData>, IAppConfiguration
Note that the inheritance scheme for the config data element is ConfigData → GeneralConfigData → LoginConfigData → AppConfigData. The config data element just exposes more properties specific to login/the application etc. (like Username or StartUri) in each child.
Now, I can use this configuration concept across all my modules. As far as dependency injection goes, resolving IGeneralConfiguration, ILoginConfiguration or IAppConfiguration will yield the exact same instance. However, now general modules only need to resolve IGeneralConfiguration, modules specific to login will only need to resolve ILoginConfiguration, and app-specific modules can resolve IAppConfiugration, all so that they can access parts of their config data specific to the concern they are trying to handle. This modularity allows me to create smaller side-apps that reuse modules from the main application without having to do a lot of custom coding (for example, I can reuse the login module without the need for referencing app-specific modules) as long as I slightly alter my dependency registration.
If you are still with me up to this point, the only problem with this model is that in all of my sub classes (that inherit from ConfigurationBase<T>), they all need the ConfigData() implementation from the interface above them. This means that class LoginConfiguration needs a method definition for public GeneralConfigData GetConfig(), and class AppConfiguration needs a method defintion for both public GeneralConfigData GetConfig() as well as LoginConfigData GetConfig().
So fine. I do that. Now, in my application-specific modules, I get a compiler error. Up in my class field definitions, I have private IAppConfiguration _appConfiguration;. Later in a method, I make a reference to it:
var element = _appConfiguration.GetConfig().AppSpecificConfigElement;
The compiler is confused, saying
the call is ambiguous between the following or properties 'IConfiguration.GetConfig()' and 'IConfiguration.GetConfig()'
Why doesn't the compiler see that the type is IAppConfiguration and define the call to GetConfig() to the AppConfiguration's GetConfig() (where T is defined as AppConfigData)?
Is there an obvious way to disambiguate the call to GetConfig() using my scheme?
If I understand correctly then what you just did is that you have two methods that have same signature except for the return value which cannot be resolved automatically. Compiler doesn't (and cannot) traverse all subclasses derived from ConfigData to determine that AppSpecificConfigElement belongs to AppConfiguration and pick overload based on that - even if it did you can have multiple classes that have AppSpecificConfigElement property so it won't be much wiser. You need to help compiler understand what you need, either by typing _appConfiguration to proper type or using typed descendant of ConfigData instead of var in your statement first and then get property.
In both cases I think you seriously over-engineered and I would suggest to step back and reconsider your approach. As #zaitsman said these objects should be POCOs and have different loader (DB, filesystem, ...) implementing simple Load/Save interface that can be then passed to DI based on context.

Resolve all derived classes of generic abstract class using Autofac

I'm building a program that will be processing messages from various topics. Since the data on each topic is different, I need dedicated classes that consumes data from any given topic. I want to do so using a base class that handles the communicates with the messaging system, and derived classes that implement the handling of the message:
public abstract class MessageConsumer<T>
{
public void Start(){/*omitted*/}
/* Other abstract properties and methods here to support template pattern*/
}
The Start method will tell the MessageConsumer to start pulling in new message. Examples of derived classes are:
public class CreatedMessageConsumer : MessageConsumer<CreatedMessage>
{
/*Implementation omitted*/
}
public class DeletedMessageConsumer : MessageConsumer<DeletedMessage>{}
In the code snippet above, I omitted the required constructor arguments, but it's easy to imagine how a DiContainer can be useful here. I use Autofac. The registration of CreatedMessageConsumer and DeletedMessageConsumer using Autofac works well.
My problem is how to resolve all classes that derives from MessageConsumer<>.
This SO post discusses how to resolve a given derived type, but I want to resolve all types that derive from MessageConsumer. Subsequently I want to call the Start method on all of them, e.g. something like
foreach(var consumer in container.Resolve<IEnumerable<MessageConsumer<??>>())
{
consumer.Start();
}
However, because I cannot provide the generic argument, it will not compile. Any idea how to do this? I'm using Autofac 4.2.1.
If you do not care about the generic argument, (which you don't otherwise you would have specified a generic argument in your last code block), then:
Define an interface (with method Start)
Implement that on your type(s)
Add it to the As chain where you define your Autofac registrations
Resolve the new interface
Updated code:
public interface IStartable {
void Start();
}
public abstract class MessageConsumer<T> : IStartable
{
public void Start(){/*omitted*/}
/* Other abstract properties and methods here to support template pattern*/
}
Caling code:
foreach(var consumer in container.Resolve<IEnumerable<IStartable>>())
{
consumer.Start();
}

Generic Vs Dependency injection

Is there any difference between Generic Classes and Dependency injection ? Are they not ways to implement Inversion of Control
Is generic class not a way to implement Dependency Injection with added benefits of compile time safety ?
For Example, if I have a node class, then I can define as following
class Node<T> where T : ISomeInterface
{
..
..
}
class Node
{
ISomeInterface obj
public Node(ISomeInterface inject)
{
obj = inject;
}
}
UPDATE 2
With New
class Node<T> where T : ISomeInterface, new()
{
ISomeInterface obj
public Node()
{
obj = new T();
}
}
Update 3
#akim : I have made the example that you asked for using Generics
Repository using Generics
Interface IRepository
{
public DataTable GetAll();
}
public class ProductRep : IRepository
{
public DataTable GetAll()
{
//implementation
}
}
public class MockProductRep : IRepository
{
public DataTable GetAll()
{
//mock implementation
}
}
public class Product<T> where T : IRepository, new()
{
IRepository repository = null
public Product()
{
repository = new T();
}
public List<Product> GetProduct()
{
DataTable prodlst = repository.GetAll();
//convert to List of products now
}
}
//so while using the Product class, client would Supply ProductRep class and in NUnit you //would supply MockProductRep class
Product<ProductRep> obj = new ProductRep<ProductRep>();
List<Product> lst = obj.GetProduct();
//in NUnit
Product<MockProductRep> obj = new ProductRep<MockProductRep>();
List<Product> lst = obj.GetProduct();
They are not the same. Generic types allow you to define functionality that can be applied to a wide range of other types. However when you instantiate a generic class, the compiler makes a reference to the actual types that were passed as generic parameters. So the declaration is static and cannot change after compilation. For example, I can write code that instantiates your Node class:
Node<SomeImplementation> node1 = new Node<SomeImplementation>();
Node<SomeOtherImplementation> node2 = new Node<SomeOtherImplementation>();
I am reusing your Node class in different scenarios, but once I have compiled my assembly, I cannot change the generic type of my variables (node1 and node2).
Dependency Injection (and IoC containers), on the other hand, allow you to change the functionality of your app at runtime. You can use Dependency Injection to swap out one implementation of ISomeInterface with a totally different implementation at runtime. For example, in your second node class, I can use an IoC container to create the Node class... something like:
Node n = Container.Create<Node>();
The IoC container then figures out how to instantiate the Node class based on some configuration. It determines that the constructor needs an implementation of ISomeInterface, and it knows how to build an implementation at runtime. I can change my configuration for the IoC container and execute the same assembly/code and a different implementation of ISomeInterface will be created and passed to the constructor of Node.
This is useful in unit tests, because you can mock out certain parts of your application so that one specific class can be tested. For example, you may want to test some business logic that usually accesses a database. In your unit test, you can mock your data access logic and inject new functionality that returns 'static' data that is needed to test each particular business case. This breaks your tests dependency on the database and allows for more accurate/maintainable testing.
Edit
With regards to your update, the parameter-less constructor restriction may not always be desired. You may have a class (written by you or a third party) that requires parameters. Requiring a class to implement a parameter-less constructor may effect the integrity of the application. The idea behind the DI pattern is that your Node class doesn't need to know how the class was actually created.
Suppose you had many layers of classes/dependencies. With generic types, it might look like this:
class MyClass<T>
where T : IUtilityClass
{
...
}
class UtilityClass<T> : IUtilityClass
where T : IAnotherUtilityClass
{
...
}
class AnotherUtilityClass : IAnotherUtilityClass
{
...
}
In this case, MyClass uses UtilityClass, and UtilityClass depends on AnotherUtilityClass. So when you declare MyClass, you must know every dependency down the line... not just the dependencies of MyClass, but also the dependencies of UtilityClass. This declaration looks something like this:
MyClass<UtilityClass<AnotherUtilityClass>> myTestClass =
new MyClass<UtilityClass<AnotherUtilityClass>>();
This would get cumbersome as you add more and more dependencies. With DI, your caller doesn't need to know about any of the nested dependencies because the IoC container automatically figures them out. You just do something like this:
MyClass myTestClass = Container.Create<MyClass>();
There's no need to know anything about the details of MyClass or it's utility classes.
There are usually other benefits to IoC containers as well, for example many of them provide forms of Aspect Oriented Programming. They also allow you to specify the lifetime of an object, so an object could be a singleton (only one instance will be created, and the same instance will be returned to all callers).
Generics introduce the concept of type parameters, which make it possible to design classes and methods that defer the specification of one or more types until the class or method is declared and instantiated by code msdn. And generics with all their restrictions and check are applied during compile time using static analysis.
In other hand, Dependency injection is a software design pattern that allows a choice of component to be made at run-time rather than compile time wiki. And object coupling is bound at run time by an assembler object and is typically not known at compile time using static analysis wiki.
Answer on your question: one applied at compile time using static analysis, another applied at run time using XML or in-code configuration (it should be also valid for compile). Using Dependency injection decision about binding will be postponed until more information or configuration will be available from the context. So generics and dependency injection are different, and used for different purpose.
Sample #3 answer
Let's move one step further and provide Repository<Entity> to Controller and think about it usage. How are you going to implement controler's constructor:
public ControlFreakController<Repository<Entity>>()
{
this.repository = new Repository<Entity>(); // here is a logical problem
}
or
public ControllerWithInjection(IRepository repository)
{
this.repository = repository;
}
And how will you cover ControlFreakController with tests, if it depends on Repository<Entity> (literally hardcoded)? What if Repository<Entity> has no default constructor, and has its own dependencies and life time (for example, there should be one and only one repository rep HTTP request)? What if next day it will be required to audit work with Repository<Entity>?
I'm going to assume you mean your generic class to look like this:
class Node<T> where T : ISomeInterface {
T obj;
public Node(T inject) {
obj = inject;
}
}
..in which case, you're just opening up a generic type for dependency injection (with a restraint). You haven't discovered a different "method" of dependency injection - it is still dependency injection.
This wouldn't be very useful in a "real-world" scenario. You've made assumptions on how the type parameter would be used purely based on injecting it and restraining it. Also, you'll only ever be able to inject 1 single type of object into this, which is a very bad assumption.
After your update using new(), you've got even more issues. Your injected type must allow parameterless construction. That limits you even further.

Make sure that target inherit some interface for custom attribute

I need to create some custom attributes, to be used for my reflection functions.
Here is the usecase, as I see it:
the user creates some class and marks it with my special attribute ([ImportantAttribute] for example)
then the user does something with functions from my library. Those functions find classes with [ImportantAttribute] and do something with them
The main problem is that functions in my library expects, that classes wich was marked with [ImportantAttribute] inherit my interface (IMyInterface for example)
Is there any way to let user know if he mark his class with [ImportantAttribute] and forget to inherit IMyInterface during compilation, not in run time. Some way to specify that this attribute is only for classes that inherit IMyInterface.
Same with attributes for properties and fields.
Is there any way to let user know if he mark his class with
[ImportantAttribute] and forget to inherit IMyInterface during
compilation, not in run time
Simple answer: no, this is not possible. Not at compile-time. You can check this at runtime though using reflection.
The best you could do with attributes at compile-time (except some special system attributes such as Obsolete but which are directly incorporated into the compiler) is specify their usage with the [AttributeUsage] attribute.
I've used the strategy you mention in a couple of the frameworks I've built with good success. One such example is for providing metadata to a plug-in infrastructure:
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=false)]
public class PluginAttribute : Attribute
{
public string DisplayName { get; set; }
public string Description { get; set; }
public string Version { get; set; }
}
public interface IPlug
{
void Run(IWork work);
}
[Plugin(DisplayName="Sample Plugin", Description="Some Sample Plugin")]
public class SamplePlug : IPlug
{
public void Run(IWork work) { ... }
}
Doing so allows me to figure out information about plug-ins without having to instantiate them and read metadata properties.
In my experience in doing so, the only way I've found to enforce that both requirements are met is to perform runtime checks and make sure it is bold and <blink>blinking</blink> in the documentation. It is far from optimal but it is the best that can be done (that I've found). Then again I'm sure there is a better way to go about handling this but so far this has been pretty solid for me.

Categories