Generic Class Lists used with Strategy Pattern - c#

I want to use generic classes with strategy pattern along with dependency injection in Asp.net
Definition of interface and concrete class
public interface IPaymentMethod<T>
{
string Name { get; set }
}
public interface PaymentMethod<T> : IPaymentMethod<T> where T: class
{
public string Name { get; set; }
}
Startup.cs
services.AddScoped(typeof(IPaymentMethod<>), typeof(PaymentMethod<>));
In the application
public class PaymentResolver
{
public PaymentResolver(List<IPaymentMethod<????>> paymentMethods)
{ ... }
public IPaymentMethod Resolve(string name)
{
return _paymentMethods.FirstOrDefault(item => item.Name == name);
}
}
How can I get the collection of IPaymentMethod instances from the dependency injection? PaymentResolver.Resolve method doesn't seem to be correct.

What you are looking for is kind of conflict to your self. So basically, you want to get a service when you know the service name. Then, my question is if you know service name
_paymentResolver.GetPaymentMethod("CreditCard/DebitCard")
you must know service type as well
class Invoice
{
public Invoice(IPaymentMethod<CreditCard> cc, IPaymentMethod<DeditCard> dc) {}
}
So what stops you from using a type rather than a name? Not to mention that it offers you strongly type so you don't have a risk of mistype the name.
Hope this helps clear your mind.

Related

Couple related types together to control use in code using generics

I am trying to limit the use of types by chaining the aggregate IAggregate, the aggregate event IDomainEvent, and Identity together with generics, I have snipped the below code to give context of the issue of what I have got so far.
I have the following interfaces:
public abstract class Identity<T>
{
protected abstract string GetIdentity();
}
public interface IAggregate<T>
{
Identity<T> Identity { get; }
}
public interface IDomainEvent<TIdentity,TIdentity>
where T : Identity<TIdentity>
{
TIdentity Id { get; }
}
I implement with the below:
public class TestUserId : Identity<TestUser>
{
public TestUserId(string name) { Name = name; }
readonly public string Name;
protected override string GetIdentity() => Name.ToLowerInvariant();
}
public class TestUser : IAggregate<TestUser>
{
public TestUser(TestUserId id)
{
Id = id;
var ev = new TestUserCreated()
}
public TestUserId Id { get; }
public Identity<TestUser> Identity => Id;
}
public class TestUserCreated : IDomainEvent<TestUserId, TestUser>
{
public TestUserCreated() { }
public TestUserId Id => throw new NotImplementedException();
}
Then in the command handler, for this event to be used (and for me to be able to obtain the TestUserId which should be member of the domainEvent object).
public interface IDomainEventHandler<TEvent>
{
void Handle(TEvent domainEvent, bool isReplay);
}
That gives me the code:
public class TesterHandler : IDomainEventHandler<TestUser, TestUserCreated>
{
public void Handle(TestUserCreated domainEvent, bool isReplay)
{
// can access the ID (of type TestUserId)
var testUserId = domainEvent.Id;
}
}
So the above TesterHandler is fine exactly how i would want - however the compiler is failing on class TestUserCreated : IDomainEvent<TestUserId, TestUser> with The type TestUserId' cannot be used as type parameter 'TIdentity' in the generic type or method 'IDomainEvent<TIdentity, Type>'. There is no implicit reference conversion from 'TestUserId' to 'Identity<TestUser>'.
What I want is to couple (without OO inheritance) the event to the aggregate, so that it is tied to a specific aggregate type (i.e. specific events are tied to a specific entity, and the entity ID is part of the event type as a field), I want to try and make it impossible to code event handlers for unrelated aggregates.
I am trying to implement but the compiler complains of boxing and implicit casting errors (depending on what i try/guess), in short I am unsure how to code the above.
Given I was unable to create running code as per comments requested (hence the reason for the post) and general complexity, I decided using generics in this way was a bad idea with rationale below.
I currently have code which calls the handler as follows (and this is working fine) passing in the sourceIdentity external to the domainEvent object:
public interface IDomainEventHandler<TIdentity, TEvent>
where TIdentity : IIdentity
where TEvent : IDomainEvent
{
void Handle(TIdentity sourceIdentity, TEvent domainEvent, bool isReplay);
}
I am passing in the aggregate ID external to the IDomainEvent object (and this is desired to keep the events, from an event sourcing perspective, as simple as possible as simple POCO objects without inheritance or involving any framework).
The reason for the question was I just wanted to explore all options with generics (so the domainEvent object could have an interface that would give an ID field) but it started to get complicated quickly, specifically additional template parameters would be required since we are inferring relationships via templates, rather than OO relationships.
Without OO, the relationship would need to be defined somewhere by adding additional types to templates to tie them together interface IDomainEvent<TIdentity,TAggregate,TEvent> and interface IDomainEventHandler<TIdentity, TAggregate, TEvent>, in this case OO inheritance would be preferred and result in way less code.
All this was done to give an interface to obtain the ID, however as if an ID is really needed it can be incorporated in the event as a normal field (without the need for complex OO relationships or templates).
public interface IDomainEvent
{
DateTime OccurredOn { get; set; }
Guid MessageId { get; set; }
}
public class TestUserCreated : IDomainEvent
{
// id can be accessed by whatever needs it by being
// defined explicity within the domain event POCO
// without needing any base class or framework.
public readonly TestUserId Id;
public readonly string Name;
public TestUserCreated(TestUserId id, string name)
{
Id = id;
Name = name;
}
}

The current type, "IAdmissionRepository," is an interface and cannot be constructed. Are you missing a type mapping? [duplicate]

This question already has an answer here:
Unity: The current type is an interface and cannot be constructed
(1 answer)
Closed 5 years ago.
I am new to repository pattern and trying to implement that in my project.
I am having entity class Admission.cs
public class Admission
{
public long AccountID { get; set; }
public long ClientID { get; set; }
public long AdmissionID { get; set; }
}
Then i am having interface like this:
namespace Common.Interfaces
{
public interface IAdmissionLogic:IDisposable
{
Admission GetAdmission(long admissionId);
void UpdateAdmission(Admission admission);
}
}
Then i am having business logic class in different project as:
public class AdmissionLogic:IAdmissionLogic
{
private IAdmissionRepository data;
public AdmissionLogic()
{
var dependencyContainer = new UnityContainer().LoadConfiguration();
dependencyContainer.RegisterType(typeof(IAdmissionLogic));
data = dependencyContainer.Resolve<IAdmissionRepository>();
}
public void Dispose()
{
data.Dispose();
}
}
Then i am having interface in data project as:
namespace Data.Interfaces
{
public interface IAdmissionRepository:IDisposable
{
CommonEntities.Admission GetAdmission(long admissionId);
void UpdateAdmission(CommonEntities.Admission admission);
}
}
Then i am having actual repository class in same project as above one as:
namespace Data.Repositories
{
public class AdmissionRepository : EntitiesRepositoryBase<Data.Admission, CommonEntities.Admission>, IAdmissionRepository
{
public CommonEntities.Admission GetAdmission(long admissionId)
{
}
}
}
When i write the following line in actual aspx page where i am querying;
AdmissionLogic admissionLogic = new AdmissionLogic();
Admission admission = admissionLogic.GetAdmission(AdmissionId);
I am getting in AdmissionLogic as :
The current type, "IAdmissionRepository," is an interface and cannot be constructed. Are you missing a type mapping?
What i am doing wrong here?
The registration part does not seem to be correct. You are registering the IAdmissionLogic but without an implementation. Then you never resolve an IAdmissionLogic component, but an IAdmissionRepository.
You should instead register the Repository with its implementing type.
dependencyContainer.RegisterType<IAdmissionRepository, AdmissionRepository>();
Also your registration code should go to the composition root (once per application) and not in a class implementing business logic. See http://blog.ploeh.dk/2011/07/28/CompositionRoot/ for an explanation.
dependencyContainer.RegisterType(typeof(IAdmissionLogic));
There are likely two issues here.
a) You should be registering the concrete type (i.e. class), not the interface.
b) You shouldn't be doing this in the constructor of AdmissionLogic (otherwise it will run many times).
Your dependencyContainer should be being created (and assigned to a static variable) once at startup. Registrations should be setup at the same time (once, not repeatedly).

MEF Metadata ensure class implements interface stated in Metadata attribute

Hi I have a a MEF container which detects metadata attributes and I would like to expand on this and allow classes to implement additional intefaces (in the example below, where i want to implement an additional interface IPluginSettings).
The module GUID identifier is critical as it is reconciled with a module ID in my database application, if I query the MEF container for my imported interfaces I can loop through them:
foreach (Lazy<T,IPluginMetadata> moduleInAssembly in m_Container.GetExports<T, IPluginMetadata>();)
{
T value = moduleInAssembly.Value; // instantiate an object of type T to test for implementations of other interfaces...
if (value is IPluginSettings)
{
// this module also contains an interface for settings!
}
Guid moduleInAssemblyId = Guid.Parse(moduleInAssembly.Metadata.PluginID);
}
I have some questions:
1) In the above scenario, I have to instantiate the class to test if I it implements a specific interface, is there a better way of doing this with Metadata and enhance the PluginExportAttribute to accept a list of secondary interface types?
2) How can I tell MEF container to import types that only have the PluginExportAttribute?
3) Or instead of having each plugin interface flexilbe/free to declare its own interface, would i be better off for plugins to implement a well-known plugin interface which contained a factory to instantiate the specific plugin interface? (Example of what i am asking is at the bottom of the code - last section)
4) Thanks to one proposed answer i am using code structured as per question 4 snipit below and it works! Out of curiosity, is there anyway to merge multiple seperate Export attributes into the PluginExportAttribute, perhaps in a constructor parameter to take a list of additional types to register?
Thanks,
Chris
public interface IPluginMetadata
{
string PluginID { get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class PluginExportAttribute : ExportAttribute, IPluginMetadata
{
public PluginExportAttribute(Type t, string guid)
: base(t)
{
PluginID = guid.ToUpper();
}
public string PluginID { get; set; }
}
[PluginExport(typeof(IAccountsPlugin),"BE112EA1-1AA1-4B92-934A-9EA8B90D622C")]
public class BillingModule : IAccountsPlugin, IPluginSettings
{
// my class contents
}
or would i be better of doing something like this...?
// or would i be better of by implementing a plugin base, and getting instances of the plugin via a secondary factory?
public interface IWellKnownPluginBase
{
Guid PluginID { get; }
Version Version { get; }
IPluginSettings Settings { get; }
Type GetPluginInterfaceType { get; }
object PluginInterfaceFactory();
}
public interface IMyPlugin
{
void DoSomethingCool();
}
[Export(typeof(IWellKnownPluginBase))]
public class MyPluginWrapper : IWellKnownPluginBase
{
private readonly string ID = "BE112EA1-1AA1-4B92-934A-9EA8B90D622C";
Guid PluginID { get { return Guid.Parse(ID); } }
Version Version { get {return new Version(1,0,0); } }
IPluginSettings Settings { get { return new SomethingThatImplementsIPluginSettings(); }
Type GetPluginInterfaceType { get { return gettype(IMyPlugin); }
object PluginInterfaceFactory() { return new MyPlugin(); }
class MyPlugin : IMyPlugin
{
void DoSomethingCool() {}
}
}
Question 4 - can PluginExport be rewritten to register multiple interfaces with a list of interfaces in the constructor?
[Export(typeof(IPluginSettings))]
[PluginExport(typeof(IAccountsPlugin),"BE112EA‌​1-1AA1-4B92-934A-9EA8B90D622C")]
public MyModule class : IModule, IPluginSettings
{
}
In the above scenario, I have to instantiate the class to test if I it implements a specific interface, is there a better way of doing this with Metadata and enhance the PluginExportAttribute to accept a list of secondary interface types?
Normally you would do this by having multiple exports:
[Export(typeof(IPluginSettings))]
[Export(typeof(IModule))]
public class MyModule : IModule, IPluginSettings
{
}
Instead of checking whether an interface is present, the consumer (i.e. the importer, or in your case the caller of GetExports) can then just ask for the correct interface.

Is there a way to dial down the OData Service reflection provider?

This is a continuation of an issue I'm still experiencing here. I'm trying to prevent the OData reflection provider from trying to expose ALL of the CLR classes in my assembly.
Consider the following CLR class:
public class Foo
{
public Guid FooID { get; set; }
public string FooName { get; set; }
}
And the following class to expose Foo as an IQueryable collection:
public class MyEntities
{
public IQueryable<Foo> Foos
{
get
{
return DataManager.GetFoos().AsQueryable<Foo>();
}
}
}
And the following DataService class:
public class MyDataService : DataService<MyEntities>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule("Foos", EntitySetRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}
}
This all works hunkey dorey and the DataService can display a collection of Foo. But if change Foo to extend a very simple base object such as:
public class Foo : MyObjectBase
{
public Guid FooID { get; set; }
public string FooName { get; set; }
}
Then (even though I'm only trying to expose 1 collection), the reflection provider grabs ALL objects that extend MyObjectBase, causing loads of errors.
The base class is a simple abstract class that implements a number of interfaces and provides another property such as:
public abstract class MyObjectBase: IDataObject, IDataErrorInfo, INotifyPropertyChanged, IDisposable
{
public virtual Guid ID { get; set; }
}
Even putting IgnoreProperties on any public properties here doesn't help. Is there any way to dial down what the reflection provider is doing?
You could set:
config.SetEntitySetAccessRule("TypeNotAccessible", EntitySetRights.All);
to
config.SetEntitySetAccessRule("TypeNotAccessible", EntitySetRights.None);
On any classes you don't want accessible. I do this using the help of a custom attribute that indicates the rights I want for a particular class. This in combination with looping over all known types (that implement my attribute), makes it possible to do this without explicit code to set each class individually.
I was unable to find a way to dial down the reflection provider with a rich data model. I ended up building a custom provider as indicated here.
If someone provides a way to dial down the reflection provider, I'll accept that answer.

Creating read-only versions of classes in a complex object structure

In my current project I need to be able to have both editable and read-only versions of classes. So that when the classes are displayed in a List or PropertGrid the user is not able to edit objects they should not be allowed to.
To do this I'm following the design pattern shown in the diagram below. I start with a read-only interface (IWidget), and then create an edtiable class which implements this interface (Widget). Next I create a read-only class (ReadOnlyWidget) which simply wraps the mutable class and also implements the read only interface.
I'm following this pattern for a number of different unrelated types. But now I want to add a search function to my program, which can generate results that include any variety of types including both mutable and immutable versions. So now I want to add another set of interfaces (IItem, IMutableItem) that define properties which apply to all types. So IItem defines a set of generic immutable properties, and IMutableItem defines the same properties but editable. In the end a search will return a collection of IItems, which can then later be cast to more specific types if needed.
Yet, I'm not sure if I'm setting up the relationships to IMutable and IItem correctly. Right now I have each of the interfaces (IWidget, IDooHickey) inheriting from IItem, and then the mutable classes (Widget, DooHickey) in addition also implement IMutableItem.
Alternatively, I was also thinking I could then set IMutableItem to inherit from IItem, which would hide its read-only properties with new properties that have both get and set accessors. Then the mutable classes would implement IMutableItem, and the read-only classes would implement IItem.
I'd appreciate any suggestions or criticisms regarding any of this.
Class Diagram
Code
public interface IItem
{
string ItemName { get; }
}
public interface IMutableItem
{
string ItemName { get; set; }
}
public interface IWidget:IItem
{
void Wiggle();
}
public abstract class Widget : IWidget, IMutableItem
{
public string ItemName
{
get;
set;
}
public void Wiggle()
{
//wiggle a little
}
}
public class ReadOnlyWidget : IWidget
{
private Widget _widget;
public ReadOnlyWidget(Widget widget)
{
this._widget = widget;
}
public void Wiggle()
{
_widget.Wiggle();
}
public string ItemName
{
get {return _widget.ItemName; }
}
}
public interface IDoohickey:IItem
{
void DoSomthing();
}
public abstract class Doohickey : IDoohickey, IMutableItem
{
public void DoSomthing()
{
//work it, work it
}
public string ItemName
{
get;
set;
}
}
public class ReadOnlyDoohickey : IDoohickey
{
private Doohickey _doohicky;
public ReadOnlyDoohickey(Doohickey doohicky)
{
this._doohicky = doohicky;
}
public string ItemName
{
get { return _doohicky.ItemName; }
}
public void DoSomthing()
{
this._doohicky.DoSomthing();
}
}
Is it OK to create another object when you need a readonly copy? If so then you can use the technique in the included code. If not, I think a wrapper is probably your best bet when it comes to this.
internal class Test
{
private int _id;
public virtual int ID
{
get
{
return _id;
}
set
{
if (ReadOnly)
{
throw new InvalidOperationException("Cannot set properties on a readonly instance.");
}
}
}
private string _name;
public virtual string Name
{
get
{
return _name;
}
set
{
if (ReadOnly)
{
throw new InvalidOperationException("Cannot set properties on a readonly instance.");
}
}
}
public bool ReadOnly { get; private set; }
public Test(int id = -1, string name = null)
: this(id, name, false)
{ }
private Test(int id, string name, bool readOnly)
{
ID = id;
Name = name;
ReadOnly = readOnly;
}
public Test AsReadOnly()
{
return new Test(ID, Name, true);
}
}
I would suggest that for each main class or interface, there be three defined classes: a "readable" class, a "changeable" class, and an "immutable" class. Only the "changeable" or "immutable" classes should exist as concrete types; they should both derive from an abstract "readable" class. Code which wants to store an object secure in the knowledge that it never changes should store the "immutable" class; code that wants to edit an object should use the "changeable" class. Code which isn't going to write to something but doesn't care if it holds the same value forever can accept objects of the "readable" base type.
The readable version should include public abstract methods AsChangeable(), AsImmutable(), public virtual method AsNewChangeable(), and protected virtual method AsNewImmutable(). The "changeable" classes should define AsChangeable() to return this, and AsImmutable to return AsNewImmutable(). The "immutable" classes should define AsChangeable() to return AsNewChangeable() and AsImmutable() to return this.
The biggest difficulty with all this is that inheritance doesn't work terribly well if one tries to use class types rather than interfaces. For example, if one would like to have an EnhancedCustomer class which inherits from BasicCustomer, then ImmutableEnhancedCustomer should inherit from both ImmutableBasicCustomer and ReadableEnhancedCustomer, but .net doesn't allow such dual inheritance. One could use an interface IImmutableEnhancedCustomer rather than a class, but some people would consider an 'immutable interace' to be a bit of a smell since there's no way a module that defines an interface in such a way that outsiders can use it without also allowing outsiders to define their own implementations.
Abandon hope all ye who enter here!!!
I suspect that in the long run your code is going to be very confusing. Your class diagram suggests that all properties are editable (or not) in a given object. Or are your (I'm)mutable interfaces introducing new properties that are all immutable or not, separate from the "core"/inheriting class?
Either way I think you're going to end up with playing games with property name variations and/or hiding inherited properties
Marker Interfaces Perhaps?
Consider making all properties in your classes mutable. Then implement IMutable (I don't like the name IItem) and IImutable as a marker interfaces. That is, there is literally nothing defined in the interface body. But it allows client code to handle the objects as a IImutable reference, for example.
This implies that either (a) your client code plays nice and respects it's mutability, or (b) all your objects are wrapped by a "controller" class that enforces the given object's mutability.
Could be too late :-), but the cause "The keyword 'new' is required on property because it hides property ..." is a bug in Resharper, no problem with the compiler. See the example below:
public interface IEntityReadOnly
{
int Prop { get; }
}
public interface IEntity : IEntityReadOnly
{
int Prop { set; }
}
public class Entity : IEntity
{
public int Prop { get; set; }
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var entity = new Entity();
(entity as IEntity).Prop = 2;
Assert.AreEqual(2, (entity as IEntityReadOnly).Prop);
}
}
Same for the case without interfaces. The only limitation, you can't use auto-properties
public class User
{
public User(string userName)
{
this.userName = userName;
}
protected string userName;
public string UserName { get { return userName; } }
}
public class UserUpdatable : User
{
public UserUpdatable()
: base(null)
{
}
public string UserName { set { userName = value; } }
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var user = new UserUpdatable {UserName = "George"};
Assert.AreEqual("George", (user as User).UserName);
}
}

Categories