How do I enforce these limits (business limits)? - c#

I want my site to support different subscription types, free, premium and etc.
So far I made an abstract class that is like this
public abstract class Limits
{
public int PostLimit { get; protected set; }
protected Limits(int postLimit)
{
PostLimit = postLimit;
}
public bool IsLimitReached(int postCount)
{
return postCount > PostLimit
}
}
public class FreeLimit : Limits
{
private const int postLimit = 1;
public FreeLimit()
: base(postLimit)
{
}
}
So now I did this for all my account types. Now the problem is I don't know how to actually use this class.
For instance I have a service layer call PostService and in this class I have
public void CreatePost(Post post)
{
// do stuff here
}
Now in this method I don't know how to check if they reached the limit. I don't know how to check because I am unsure how to find out if I should be using the FreeLimit or PremiumLimit or what account they have.
I am thinking that I first have to figure out their Role and then somehow use that information to create the right class.
I guess I could have something like
public void CreatePost(Post post, PlanType planType)
{
Limits limit;
switch(planType)
{
case planType.Free:
limit = new FreeLmit()
break;
}
if(limit.IsLimitReached())
{
// do stuff
}
}
I don't like this way as now for every method that needs to check a limit will have to do this. I will have a few methods that require this check in my service layer.
So I was thinking of putting it in my constructor but I don't know if it is good to have a switch statement in a constructor.

You could use an interface ILimit
interface ILimit
{
int PostLimit { get; protected set; }
bool IsLimitReached(int postCount);
}
Now you can have several other classes (Free, Premium, Super) that implement this interface. In your service method CreatePost you can just pass any instance of a class that implements the interface and use it - there's no need to distinguish them anymore since they all support the same interface.
public void CreatePost(Post post, ILimit limit)
{
if(limit.IsLimitReached())
{
// do stuff
}
}

Well, the Limit property is tied to what entity? I suppose it's tied to the Blog (or maybe a Forum) and it is persisted on a DB or something else.
If so, you can do something like this:
public void CreatePost(Post post)
{
if(post.Blog.IsLimitReached())
{
// do stuff
}
}
The Blog.IsPostLimitReached() should call this.Limit.IsLimitReached from itself.
I hope you can understand what I said :)

If you have different types of user, you can tie their accounts (once they've logged in) to different RoleTypes. Then you can use HttpContext.Current.User.IsInRole("RoleName") to see if they are in a specific role, and use that as your basis for showing/hiding functionality.

Related

Use a sort of Intermediate models

I am writing a program that synchronizes playlists among different streaming services, the problem is every service uses different structures and functions.
I want to make it "modular" so i can add new services and syncronize them with the others without programming them for every service i have already in the application and the best idea i came out with is to implement it by using a sort of intermediate language (or intermediate models), e.g.
namespace Service1
{
class Service1Album
{
public string ID { get; set; }
public Service1Artist Artist { get; set; }
//Some other props...
public IntermediateAlbum ToIntermediate()
{
//conversion...
}
}
class Service1Artist
{
//Some props...
public string ID { get; set; }
public IntermediateArtist ToIntermediate()
{
//conversion...
}
}
}
namespace Intermediate
{
class IntermediateArtist
{
//Props that every service has in common...
}
class IntermediateAlbum
{
//Props that every service has in common...
}
}
In this way every service I implement accept as parameter for its functions Intermediate models and outputs his own models that can be converted.
Service1Album album = service1.GetAllAlbums()[0];
IntermediateAlbum intermediateAlbum = album.ToIntermediate();
service2.AddAlbum(intermediateAlbum);
service3.AddAlbum(intermediateAlbum);
Is there a way I can implement this more elegantly? And if so, is there a way I can inherit every service from something like a ServiceContainer that abstracts every service like this?
var sList = new List<ServiceContainer>{};
sList.Add(new Service1());
sList.Add(new Service2());
foreach (var service in sList)
{
service.addAlbum(new IntermediateAlbum()
{
//properties
});
}
Luca - Welcome! You're discovering the need for some design patterns in your code. That's really great - it means things are getting complex enough that you can start to lean on the patterns others have spent years refining in building your solution.
#1 - Switch to using Interfaces + Design Patterns
If I were you, I'd start by abstracting everything to interfaces (eg - you'd run your work in each Service against IAlbum's and IArtist's instead of concrete implementations).
Then, once your interfaces are in place, take a look at the .net code for the gang-of-four patterns to figure out how to layout the work.
#2 - The basics
There's a lot of code to write, but the skeleton might end up looking like this
namespace MusicService
{
public interface IAlbum {
//common album properties/methods
}
public interface IArtist {
//common artist properties/methods
}
internal abstract class AlbumBase:IAlbum {
// implement common functions and properties if you have them...
// otherwise, skip this
}
internal abstract class ArtistBase:IAlbum {
// implement common functions and properties if you have them...
// otherwise, skip this
}
}
namespace MusicService.AppleMusic
{
internal class Album:AlbumBase
{ //OR Album:IAlbum if you skipped that AlbumBase thing
//code apple music specific stuff here ...
// think of this as a "mask" that the apple album is
// wearing so that it can pretend to be an iAlbum
}
internal class Artist:ArtistBase
{
//same comments apply here
}
}
namespace MusicService.Spotify
{
internal class Album:AlbumBase
{
//GO and do liekwise with Spotify
}
internal class Artist:ArtistBase
{
//GO and do liekwise with Spotify
}
}
#3 - Implementing the actual SYNC
Now that you have the code you need for your various music services (neatly arranged, so your fellow programmers don't have to dig through your brain to figure out what you were thinking), you can code your SyncService.
I don't want to spoil the fun (sync service could use the decorator pattern or it could be a sort of composite -- not sure what your sync code needs to do), but your final sync code could be as easy as:
var myService = new SyncService();
myService.AddAppleMusic();
myService.AddSpotify();
myService.Sync();
Spoiling the Fun
OK. Fine. Here's what I'd do.
namespace MusicService {
public interface IService {
//propably a List<IAlbum> and List<IA> somewhere in here
void Sync();
}
public class SyncService {
internal List<IService> _services;
public void AddService(IService musicService) {
if(_services==null){_services=new List<IService>();}
_services.Add(musicService);
}
public void Sync() {
foreach(IService ms in _services) {
ms.Sync();
}
}
}
}
namespace MusicService.AppleMusic {
internal AppleSyncService:IService {
public AppleSyncService() {
//Do your apple-specific initializations here
}
public void Sync() {
//apple-sync
}
}
internal class ExtendService(){
public static void AddAppleMusic(this SyncService syncAgent) {
syncAgent.AddService(new AppleSyncService());
}
}
}
Obviously - none of that code compiles, and coding in notepad is probably a bad idea. But, it gives you a pattern-based alternative to your sample code above. AND - if you add a third music service, you don't run the risk of breaking apple and spotify just to wedge in that new one!
Good luck. Sounds like a fun project.

C# distinguishing incoming objects using attribute

I need a way of distinguishing class objects which a user is passing into my custom control. The reason for this, is so I can handle certain logic on the back end, completely extracted and uncontrollable by the user. The user would pass in object collections like this...
<Grid>
<nexus:NexusEditor
SourceTeams="{Binding Teams}"
SourcePlayers="{Binding Players}"
SourceLocations="{Binding Locations}"/>
</Grid>
If i were to forloop through all these objects in my custom control, I need a way of marking the incoming objects so i know which Source there were passed through.
This can't be easily done at runtime and is arguably the wrong design in C#. There are other ways to solve this. You can, for example, create a wrapper around the Connection class and inject an instance of Connection into it. ConnectionWrapper can then inherit AbstractBase
public class ConnectionWrapper: AbstractBase
{
public ConnectionWrapper(Connection connnection)
{
}
private override int _type {get; set;}
}
It's really hard to give something concrete without knowing more about your requirements, but I think something like this might do what you want:
public interface ITyped
{
int Type { get; }
}
public class Connection : ITyped
{
public string Name { get; set; } // NOTE: public setters are Bad Code(tm) for anything but the dumbest DTO objects
public int Type { get { return 1; } } // specify type for connections here
}
Usage:
foreach (var typed in connections.Concat<ITyped>(groups))
{
DoStuffWith(typed);
}

Letting only the abstract class know about its inheritors

I am making a payment system for my site. Users can select one of several payment providers to pay, but all should behave in the same way. I thought to represent this behavior like this:
public abstract class PaymentProvider {
private static var methods = Dictionary<String,PaymentProvider>
{
{"paypal",new PaymentProviderPaypal()},
{"worldpay",new PaymentProviderWorldpay()}
}
public static Dictionary<String,PaymentProvider> AllPaymentProviders
{
get {return methods;}
}
public abstract pay();
}
public class PaymentProviderPaypal : PaymentProvider {
public override pay() {
}
}
public class PaymentProviderWorldpay : PaymentProvider {
public override pay() {
}
}
You are supposed to use this by writing PaymentProvider.AllPaymentProviders["key"].pay(). The idea is that the functions using this class don't need to know about how the underlying payment provider is implemented, they just need to know the key.
However, at the moment, if you have access to the PaymentProvider class, you also have access to the inheriting classes. Its possible to instantiate a new copy of the inheriting classes, and make use of them in an unexpected way. I want to encapsulate the inheriting classes so that only the abstract PaymentProvider knows about them.
How should I do this? Different protection levels like protected don't work here - In Java, protected means that only other classes in the namespace can use that class, but in C# it means something else.
Do I have the right idea here? Or should I use a different method?
A couple of options spring to mind:
Put this in a separate assembly from the client code, and make the implementations abstract
Put the implementations inside the PaymentProvider class as private nested classes. You can still separate the source code by making PaymentProvider a partial class - use one source file per implementation
The first option is likely to be the cleanest if you don't mind separating the clients from the implementation in terms of assemblies.
Note that both of these are still valid options after the change proposed by Jamiec's answer - the "visibility" part is somewhat orthogonal to the inheritance part.
(As an aside, I hope the method is really called Pay() rather than pay() :)
Your inheritance heirachy is a bit wonky, I would be tempted to do it a similar but crucially different way.
public interface IPaymentProvider
{
void Pay()
}
// Implementations of IPaymentProvider for PaypalPaymentProvider & WorldpayPaymentProvider
public static class PaymentHelper
{
private static var providers = Dictionary<String,IPaymentProvider>
{
{"paypal",new PaymentProviderPaypal()},
{"worldpay",new PaymentProviderWorldpay()}
}
public static void Pay(string provider)
{
if(!providers.Containskey(provider))
throw new InvalidOperationException("Invalid provider: " + provider);
providers[provider].Pay();
}
}
Then the usage would be something like PaymentHelper.Pay("paypal").
Obviously if there is more data to provide to the Pay method this can be added to both the interface, and the helper. for example:
public interface IPaymentProvider
{
void Pay(double amount);
}
public static void Pay(string provider, double amount)
{
if(!providers.Containskey(provider))
throw new InvalidOperationException("Invalid provider: " + provider);
providers[provider].Pay(amount);
}

Limiting access to a public setter to specific objects (C#)

I'm trying to create a class (in C#) that serves as an environment for my application.
I'm trying to make the class dynamic, and send it as a parameter to entities in my application. The problem is, that I want to be able to change the properties of this environment class (public setters), but at the same time I want the classes that receive the environment to be unable to use these setters.
I can't seem to find a good way to phrase my question (which I figure is a part of the reason I can't find anything like this on Google or msdn), but to put shortly, I want to create a class with setters that are public only for some of my objects and not for all.
I'm currently amusing the following idea:
Avoiding the public setters all together, and expose the private fields using event registration.
The class will register to events in a new third object (sent as a parameter to the constructor). The methods that will be registered by the environment are not much more then setters, and so triggering these events will "allow access" to the private fields.
I'd love some ideas (seeing as I feel that mine isn't all that great), or better yet some patterns I could make use of.
Thanks in advance
Isn't "internal" sufficient for what you need?
And you could move the setters into an interface as explicit implementation. Then they are hidden from the public interface and only accessible if you cast to the interface.
And if you want to make really sure that nobody else can call it you can add some parameter to these functions where you expect a certain token object which you only give to trusted classes.
void SetX(int value, object token)
{
if(token!=correctToken)
throw new ArgumentException("wrong token");
x=value;
}
You could create a proxy, and send that proxy to your entity classes.
class MyClass
{
public int MyProperty { get; set; }
}
class MyProxyClass
{
public MyProxyClass(MyClass myClass)
{
_myClass = myClass;
}
private MyClass _myClass;
public int MyProperty
{
get { return _myClass.MyProperty; }
}
}
You could try using Friend assemblies. That will allow only the assemblies you specify to have access to your privates (snicker).
Maybe i understood something not quite well, but i think Jon had a quite similar problem which he described here. Maybe this can help you.
How about
class Callee
{
public void SetX(TypeOfCaller caller, int value)
{
}
}
class TypeOfCaller
{
public void Do()
{
Callee instance;
//..
instance.SetX(this, 5);
}
}
Doing so; you can also use Visual Studio' Find References feature! In case you want multiple types of caller; you can either opt for class hierarchy or can simply have required overloads
Why not return clones of your protected objects instead of the actual objects? Solves the problem without adding any more complexity.
public class MyService
{
private List<MyObject> _protectedObjects = new List<MyObject>();
public MyObject GetItem(int id)
{
return (MyObject)_protectedObjects.First(i => i.Id == id).Clone();
}
}
public class MyObject : ICloneable
{
//[...]
public object Clone()
{
return MemberwiseClone();
}
}

Nesting base classes in c#

I have 3 classes, two inherit from 1:
public class Employee {
private virtual double getBonus() { ... }
private virtual double getSalary() { ... }
}
public class Nepotism : Employee {
private double getBonus() { ... }
}
public class Volunteer : Employee {
private double getSalary() { ... }
}
So the question is sometimes there will be a Volunteer who gets the Nepotism bonus - is there some way to write the constructors to allow overriding/nesting the base class like this:
Employee Bill = new Volunteer(new Nepotism());
I'm thinking something like:
public class Volunteer : Employee {
private Employee _nest;
public Volunteer(Employee nest)
: base() {
_nest = nest;
// now what?
}
}
Basically I want some objects to have the overrides from both classes.
I would like to avoid writing the override methods to check for nested classes.
getSalary() {
return (nest != null) ? nest.salary : salary; // I want to avoid this if I can
}
How can I do this? Am I on the right track? Am I off the rails?
Instead of subclassing, you might want to consider using the Decorator Pattern.
It provides an alternative to subclassing, and it useful when you may need to add "multiple" pieces of additional functionality to a single instance of a class, which is exactly the scenario.
I think you are trying to use inheritance in an ill-advised way. This approach creates a mess of dependences and oddball business rules, which results in a rigid architecture that is hard to use and maintain.
If calculating an employees salary is dependent upon the Employee as well as "bonus traits", then it would be better to separate all three things from each other:
interface IBonusTrait
{
decimal ApplyBonus(Employee employee, decimal currentTotal);
}
class Employee
{
// ...
public decimal BaseSalary { get; set; }
public IList<IBonusTrait> BonusTraits { get; set; }
}
class SalaryCalculator
{
public decimal CalculateSalary(Employee employee)
{
decimal totalSalary = employee.BaseSalary;
foreach (IBonusTrait bonusTrait in employee.BonusTraits)
{
totalSalary = bonusTrait.ApplyBonus(employee, totalSalary);
}
return totalSalary;
}
}
If an object can be both classes at once, then you may need to rethink how you're doing your inheritance.
It seems to me that if a Volunteer can sometimes get a Nepotism bonus, then really, your Volunteer class should have a getBonus() method, and this method really belongs in the base class. It would return zero for most volunteers, but occasionally it wouldn't - there's nothing wrong with that.
Reed Copsey already said, that Decorator Pattern is something to consider.
There is also this youtube video which is very similar to your case (John Skeet is presenting it).

Categories

Resources