How do I clean up my Delegate class to be cleaner? - sdk

I am writing an SDK and wanted to know how to write things more cleanly.
For example, I have a GodManager delegate class (which will be the central class that a user can interact with) (this is pseudocode-ish):
public class GodManager {
private CloudApi cloudApi;
private SensorApi sensorApi;
private CacheApi cacheApi;
.
. And about 5 more API classes of similar sorts
.
GodManager() {
cloudApi = new CloudApi();
sensorApi = new SensorApi()
cacheApi = new CacheApi();
}
public void someCloudApiMethodAccess() {
cloudApi.someCloudApiMethodAccess();
}
.
.
. And I have about 25 other methods where GodManager delegates to API classes
.
}
How do I allow access for my users via GodManager, but remove these 25 methods that are just proxy methods for each Api class?
I know that Android Wear does something with:
public class Wearable {
public static final com.google.android.gms.wearable.DataApi DataApi;
public static final com.google.android.gms.wearable.MessageApi MessageApi;
public static final com.google.android.gms.wearable.NodeApi NodeApi;
}
Where you can access these APIs in your code:
Wearable.DataApi.getFdForAsset(...)
So I'm guessing that I can mimic this and do something like:
class GodManager {
public static CloudApi CloudApi;
GodManager {
CloudApi = new CloudApi();
}
}
Then in my implementation classes, I can:
class ImplClass {
public void method() {
GodManager.CloudApi.someCloudApiMethodAccess()
}
}
Am I missing anything? Will there be some awkward side-effects that I haven't considered? Any advice would be greatly appreciated in an effort to clean up my GodManager.
Or maybe someone has some other examples that I can look at and learn from?

Creating public fields is usually an antipattern, although there are some legid uses. The danger lies in the fact that if a user has access to your field, it can do ANYTHING with it.
If CloudApi contains public methods or public fields of it's own, that the user should NOT mess with, then te ONLY solution is to make a huge delegate class. If you have full control over CloudApi, and/or you can ensure that it's only public members are those that may be safely, and unconditionally, accessed by others, then you can make the instance public. (which is the legid use)
(Note that making a member private and making a public getter for that method that returns the instance, is exactly the same!)
Even then, you're limiting yourself because you're defining your API (of GodManager) and you're preventing yourself from EVER extending functionality of the referenced instances. For example, you might want to make calls to CloudApi synchronized, or check parameter validity, but don't want (or can) change CloudApi. If you have delegate methods, you can extend the functionality without changing your GodManager API, and existing users don't break.

Related

PlayFramework: The relation between Controller and Dependencies Injection

Now I am reading PlayFramework's official document which explains DI like this
There are two ways to make Play use dependency injected controllers.
I can't imagine how they are related, so what do they mean?
Why do we need putting the concept of DI into the Controller?
Could anyone explain?
In earlier versions of Play, controllers had static methods. This in turn lead to lots of either static code or singletons because static controllers couldn't easily share code or service objects. This also made testing harder than it had to be.
By moving to dependency injected controllers, everything can now be object-based (in place of the earlier class-based approach) and so shared instances or dedicated code can be passed into controllers.
Imagine a app that manages items of some type. Items are stored in a database, so some configuration is required.
public class StaticController extends Controller {
// active record approach
public static Result getItems() {
// static call to Item
List<Item> items = Item.findAll();
// do other stuff
}
}
When testing this, StaticController and Item are tightly coupled. Compare this to an approach using DI, in which a DAO can removed that coupling.
public class InjectedController extends Controller {
private final ItemDao itemDao;
public InjectedController(final ItemDao itemDao) {
this.itemDao = itemDao;
}
public Result getItems() {
// static call to Item
List<Item> items = itemDao.findAll();
// do other stuff
}
}
Because ItemDao can be an interface, coupling is massively reduced and testing just because a lot easier.

Using Log4Net inside an interface

I have an interface
public interface ILoggerService
{
void Info(string message);
void Warn(string message);
}
Then, i have a class which implements this interface and logs using Log4Net
public class Log4NetLoggerService : ILoggerService
{
private readonly ILog _logger;
public Log4NetLoggerService()
{
// this always returns Log4NetLoggerService class type
_logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
}
public void Info(string message)
{
_logger.Info(message);
}
}
This works fine, but the problem is that if i want to log the current class and method name, (using %class - %M), this always returns Log4NetLoggerService as the class, and as the method it returns Info as the method.
I need to get the "parent" class type, which called the logging method.
Can i inject somehow the type of the class which calls the log methods when i create the ILoggerService instance?
Have a look at the log4net source code; specifically how they implemented the ILog interface. You basically cannot use the ILog interface in your wrapper, instead you use the internal logger which accepts a parameter that instructs log4net where to look for the correct class / method in the call stack. See also this answer.
In my experience, if you need the name of the class you're logging in, you're probably logging too much and from too many places in your application. This can lead to maintenance problems. Take a look at this Stackoverflow answer to verify if you're not logging too much and if you're not violating the SOLID principles.

Passing user information down to data access

I'm working on a desktop application that has generated code for database access and uses static objects for user identification.
Now we need to expose some of the logic by webservice and we are looking for the least intrusive form to push the user information down the pipe to the database access classes.
What we came up with was to pass a delegate to the Insert / Update methods that looks like this:
public delegate string GetLogin();
public class BaseEntity : BaseNotifiableEntity, System.ComponentModel.IDataErrorInfo
{
public GetLogin Login { get; set; }
(...)
}
public static class BaseEntityHelper
{
public static SqlCommand buildUpdateCommand(BaseEntity entity)
{
UpdateDefaultValues(entity, false);
(...)
}
public static void UpdateDefaultValues(BaseEntity entity, bool affectCreationFields)
{
if (entity.Login == null && AppServer.RunningApplication.CurrentUser == null)
throw new Exception("Something went wrong");
(...)
}
}
So in our logic will would have something like this:
public class Service
{
T_DIST_Service record;
(...)
public bool Update(DataAccess.Base.GetLogin login)
{
record.Login = login;
(...)
record.Update();
}
}
This of course involves changing a lot of methods in the application.
So i was wondering if there's a seamless way to accomplish this using dependency injection (for example).
Probably some of you have already go down this road and have some insights to share.
Thank you for your time.
EDIT 1:
Using .NET
On an architectural level it sounds like me that you are attempting to put logic in the data access layer that doesn't belong there. A data access component should be nothing but an anti-corruption layer, so any logic should ideally be implemented in the calling layer.
However, if you want a more immediate fix here and now, it would be most recommendable to use the built-in Thread.CurrentPrincipal Ambient Context.
If you have special information that your user object must carry around, you can use a custom implementation of IPrincipal to create a custom User Context.

MVC Custom Attributes and Binding

I've got a project where we have our own customer registration and account management system, but certain elements of the application link to 3rd party services. These services have common functionality e.g. creating an account in their own DB, but the underlying implementation will be different for how to interactive with the third party services.
What I've done so far is create a CustomerRepository which implements ICustomerRepository. This contains all our own specific requirements. ICustomerRepository also has definitions for the common methods that all third parties will have, but these methods are set to virtual in the CustomerRepository class, which throws exceptions if they're called, requiring you to implement them in the third party classes.
Then from this, I have:
ThirdPartyACustomer : CustomerRepository, IThirdPartyACustomer
ThirdPartyBCustomer : CustomerRepository
As you can probably guess, both of those sub classes inherit and override the virtual methods, with the exception of ThirdPartyACustomer which also implements additional methods that are specific to that particular type of third party user (e.g. there might be a place where the user can edit specific features related to third party A, which third party B doesn't offer.
Now, with that out of the way, the real basis of my question:
Some of the processes (controllers) in my application can use the CustomerRepository without any problems as they only need our core functionality.
Other processes in the app require a particular type of ICustomerRepository to be passed. Anything that calls a method that was defined as virtual in CustomerRepository will need to pass either ThirdPartyACustomer or ThirdPartyBCustomer so that the correct implementation is called.
Originally in this initialisation of this type of controller I'd do something like:
public RegistrationController()
{
ICustomerRepository _customerRepository = GetCustomerRepository();
}
where GetCustomerRepository() had some logic that determined which type of ThirdParty to use, based on the subdomain, for example.
Now, what I'm thinking is that I improve this by creating a custom attribute, along the lines of this:
[ThirdPartyDependent]
class RegistrationController
{
public RegistrationController(ICustomerRepository customerRepository)
{
_customerRepository = customerRepository;
}
}
and move the population of customerRepository parameter into that attribute, e.g. the logic in GetCustomerRepository would happen in there.
I'm fairly sure something like this is doable and seems to make sense for testing purposes, but not quite sure of what I should be googling for, or whether there is a better way to do things, so looking for some guidance from someone more experienced with MVC.
That's the responsibility of your DI framework. For example Ninject provides you access to the HttpContext when configuring the dependencies, so you could pick the proper implementation based on some HttpContext value. For example:
kernel.Bind<ICustomerRepository>().ToMethod(ctx =>
{
if (HttpContext.Current.... Test something on the request or domain or whatever)
{
return new ThirdPartyACustomer();
}
return ThirdPartyBCustomer();
});
and then of course your controller will be totally agnostic. All that a controller should care is that it gets injected some repository which obeys a given contract:
public class RegistrationController: Controller
{
private readonly ICustomerRepository _customerRepository;
public RegistrationController(ICustomerRepository customerRepository)
{
_customerRepository = customerRepository;
}
}

Where should 'CreateMap' statements go?

I frequently use AutoMapper to map Model (Domain) objects to ViewModel objects, which are then consumed by my Views, in a Model/View/View-Model pattern.
This involves many 'Mapper.CreateMap' statements, which all must be executed, but must only be executed once in the lifecycle of the application.
Technically, then, I should keep them all in a static method somewhere, which gets called from my Application_Start() method (this is an ASP.NET MVC application).
However, it seems wrong to group a lot of different mapping concerns together in one central location.
Especially when mapping code gets complex and involves formatting and other logic.
Is there a better way to organize the mapping code so that it's kept close to the ViewModel that it concerns?
(I came up with one idea - having a 'CreateMappings' method on each ViewModel, and in the BaseViewModel, calling this method on instantiation. However, since the method should only be called once in the application lifecycle, it needs some additional logic to cache a list of ViewModel types for which the CreateMappings method has been called, and then only call it when necessary, for ViewModels that aren't in that list.)
If you really don't want to use a bootstrapper, then at least a static constructor is an easy way of ensuring your CreateMap is called at most once. (With less messing around and more thread proof than Jonathon's answer.)
public class AccountController : Controller
{
static AccountController()
{
Mapper.CreateMap<Models.User, ViewModels.UserProfile>();
Mapper.CreateMap<Models.User, ViewModels.ChangePassword>();
}
}
If you use profiles, you can place all of your "CreateMap" calls there. Additionally, you can create a static bootstrapper class that contains your configuration, and have the startup piece just call the bootstrapper.
OK, the way I'm currently doing it is this:
I add some logic to the constructor of my BaseController, which runs the 'CreateMappings' method, but only once per Controller Type:
public abstract class BaseController : Controller
{
public BaseController()
{
if (!controllersWithMappingsCreated.Contains(GetType()))
{
CreateMappings();
controllersWithMappingsCreated.Enqueue(GetType());
}
}
protected virtual void CreateMappings() { }
}
In each concrete controller, I use CreateMappings to declare the mappings for all the Models/ViewModels relevant to that controller.
public class AccountController : BaseController
{
public AccountController() : base() { }
protected override void CreateMappings()
{
Mapper.CreateMap<Models.User, ViewModels.UserProfile>();
Mapper.CreateMap<Models.User, ViewModels.ChangePassword>();
}
}
I also found some interesting alternatives involving Attributes here and here, however they strike me as a bit overcomplicated.

Resources