I don't understand.. if I can use import in Aurelia, why do I have to wire up the constructor with #autoinject() and all that? I'm sure I'm missing something, but, from what I can tell, I can just use my imported module whenever I want.
import something from "whatever"
export class SomeViewModel {
activate() {
// use something
}
}
Typically, in an Aurelia application, the thing you are importing isn't an instance of Something it's the class Something. To actually use whatever has been imported, you need an instance of it.
import Something from 'whatever';
let something = new Something();
When you use Aurelia's Dependency Injection system, you are utilizing a design pattern called "Inversion of Control." Instead of your class (or you) being in charge of instantiating its dependencies, it lists what dependencies it has and then has instances of the dependencies injected in to its constructor function.
This helps with testability, as now you can pass mocked instances of the dependencies to a class in your test fixtures (note that in your tests, your tests will pass the mocks to the constructor, and not rely on Aurelia's DI container).This also allows you to tap in to the Dependency Injection container's ability to be configured to create dependencies using different object lifestyles such as singletons and transient.
--- Edits to answer OP's questions from comments ---
If I import a module defined as export default class Something into an
aurelia view model using constructor injection, it does not need to be
instantiated. It is an instance of the class Something.
This is because Aurelia's Dependency Injection container is instantiating an instance for you. This is why your code looks like this:
import {inject} from 'aurelia-framework';
import Something from 'somewhere';
#inject(Something)
export class Foo {
constructor(something) {
this.something = something;
}
//...
}
and not
import Something from 'somewhere';
export class Foo {
constructor(Something) {
this.something = something;
}
//...
}
You are telling Aurelia "I need one of these, please give it to me," and Aurelia says "Sure thing, I've created one or I already had one lying around, here it is."
In other words, it appears that aurelia's constructor DI only works
with class exports, and it does instantiate the class. It looks like
if I want to import something like moment js into my aurelia view
model, I should just continue doing things the way I've always done
them (not using aurelia's DI). Does that sound correct?
This is correct. Libraries like moment give you a function to use, and not a class that can be instantiated by Aurelia. For these you would continue to use them as in the past.
Well technically you can use the imported modules without Aurelia's DI, but in most situations that would be a bad thing. The Dependency Injection layer gives you so much versatility and flexibility. It handles caching, it supports singleton and transient dependencies, handles lifetime and makes thing neater from an architectural perspective.
Related
I am trying to implement a NotificationService in a correct way from the point of view of OOP. For this I have the next interface:
abstract class NotificationsService {
void initNotificationsHandlers();
int sendGeneralNotification({String? title, String? body});
//...
}
And his subclass:
class FirebaseNotificationService extends NotificationsService {
//All implementations...
}
The problem is when I implement it. I have to instance it on the main:
NotificationsService notificationsService = new FirebaseNotificationService();
But I have to use this service in more classes,and I don't want to instance the FirebaseNotificationService in every class because I would be violating the Dependency Inversion Principle. I want other classes just know the abstraction NotificationsService.
I have thought using something like this:
abstract class NotificationsService {
///Current notification service subclass used.
static final NotificationsService instance;
//...
}
And then implementing the class this way:
Main
NotificationsService.instance = new FirebaseNotificationService();
Other class
NotificationsService.instance.initNotificationsHandlers(); // For example, it could be any method
But it doesn't look very clean because I am using the NotificationService interface to "save" the current subclass. I think it shouldn't be his responsibility.
Maybe should I make another class which "saves" the current implementation? Or apply a singleton pattern? What is the OOP most correct way to do this?
Clarification: I am not asking for a personal opinion (otherwise this question should be close). I'm asking about the correct OOP solution.
In which language are you programming? Java probably, by reading your Code.
What you actually want is Dependency Injection and a Singleton (even though I think that Singleton is overkill for a NotificationService)
If we remain at the Java Standard, it works in this way:
The classes that need your NotificationService would have a constructor annotated with #Inject and an agument of type NotificationService (not your Implementation Class) - so your consumer classes rely on something abstract rather than something concrete, which makes it easier to change the implementation.
The Dependency Injection Container or Framework would take care that when your classes are being injected by them self somewhere, that their Dependencies are being satisfied in order to be able to construct this class.
How does it actually know which Implementation belongs to an Interface?
Well it depends on the Framework or Platform you are using but you either define your bindings of the interface to the concrete class or is is looking it up with reflection (if we are using Java)
If a class gets injected with a new Instance every time or always the same instance this depends on your annotations on the class itself. For example you could annotate it with #Singleton.
I hope it helps a bit.
The Vue class component library uses the #Component decorator, and must thus be transpiled to work. Is there a way to use Vue class components without this decorator? Like, either a work-around or another similar library?
Use-case: Lower commitment for a legacy project, but still possible to analyze with tsc.
Transpiled environment is the expected scenario of use for Vue. It relies on custom .vue format and may lack some features without it, as well as the support of some third-party libraries because they rely on it.
The use of classes never was a good idea in Vue because it doesn't follow OOP paradigm. A class isn't instantiated directly but used as syntactic structure that is translated to Vue.component definition. Vue class components have inherent problems, one of which is poor support for TypeScript types. If Vue classes aren't already used in the project, there are reasons for them to not be the first choice.
In case there's a necessity to use Vue class components, this can be done in vanilla ES6 because decorators proposal is syntactic sugar, decorators are functions with specific signatures that are applied to classes and members and decorate them.
#foo
#bar()
class Baz {}
is the same as
let Baz = foo(bar()(class Baz {}))
Different decorator types are applied in different ways, also there are some differences between TypeScript and Babel legacy decorators.
#Component
class Foo extends Vue {
#Provide('bar') baz = 'bar'
}
is translated to
let Foo = class Foo extends Vue {
constructor() {
this.baz = 'bar'
}
}
Provide('bar')(Foo.prototype, 'baz')
Foo = Component(Foo);
With Vue 3 typescript is well supported, you could create your component as follows :
import { defineComponent } from 'vue'
export default defineComponent({
//the component options like data,props,computed...
})
For more details check the official docs
A running example to get started
For other dependencies I can use a #scope such as #Singleton to make it only have one instance.
For example:
#Component
#Singleton
interface ApplicationComponent {
fun getMySingleInstanceDependency(): MySingleInstanceDependency
}
#Singleton
class MySingleInstanceDependency #Inject constructor()
If I add a #subcomponent to the main component, it returns a new instance every time I require an instance. The only thing I can think of is to use the #Component.Builder to pass an instance of the subcomponent inside so it uses the same instance every time, but that doesn't sound right. Is there a better way to do this?
You are talking about different question. Lifecycle of object instance should nothing to do with subcomponent. Let me explain here your question.
By default all dependencies are created with your provide annotation. Which would be called each time we are requesting this item in different Dagger modules. Unless this particular dependency is annotated as singleton.
You subcomponent should nothing to do with above allocation.
Basically you would have one (or several) Dagger component which could include subcomponent. Their lifecycle is handled by Dagger scope.
I'm developing an application for transferring databases and directories of user-uploaded images/documents from our production server to the development server. The application is written in Coldfusion, but I don't think the language is relevant to this question - it's more of a structural/architecture question than a question specific to the language.
I'll be writing pseudo code for my examples, so please don't pick apart the syntax.
When I've seen class inheritance demonstrated, it's usually something simple like class Student extends Person() {}. Obviously, a Student is a more specialized Person, so this makes sense.
In my application, I have a class Site() which contains relevant information such as the DSN, file upload directory, etc. I perform my SQL exports in one class and my file upload exports in another class, both of which are called from within the site class(pseudo-code):
class Site {
public function exportSql() {
sqlExport = new sqlExport(this.dsn);
sqlExport.createDumpAndZipItAndStuff();
}
public function exportUploads() {
uploadsExport = new uploadsExport(this.uploadDirectory);
uploadsExport.copyAndZipFilesAndStuff();
}
}
The Site class doesn't do anything other than control the flow of traffic that is requested from the front-end of the application, everything else is handed off to one of the export classes.
This works fine for me, but I'd like to structure it properly. Right now, I have to pass Site's properties to the constructor of the export classes, and then set the export class's properties with those arguments. This causes a lot of duplication.
Would it be appropriate to have my export classes inherit the Site class so that I could access the properties directly? The export classes are not a more specialized Site, as in the Person/Student example I gave earlier. Rather, they just perform the heavy lifting for the Site class.
If this is not an appropriate situation for inheritance, how should I structure the application? As I said earlier, the way I'm doing it right now works, but I would like to take this opportunity to learn more about design patterns and write my code in a way that makes sense.
Inheritance should be use when something is a kind of another thing.
Like a dog is kind of animal, therefor it should inherit from animal.
Export is not a kind of Site, so it shouldn't inherit from it.
What you're looking for is Composition. Export should hold a reference to a Site which it exports. Then you can pass the Site object to it on contruction, and it can get the data from the site whenever you need.
Export shouldn't extend your Site class, since things that are Exports are not members of a subset of things that are Sites. Inheritance is overused, and Composition makes more sense in this case as you have done. One way you can refine your existing object model and improve testability is by using Dependency Injection.
Calling "new" inside an object instance makes your object model more brittle and harder to test. You could inject the instances of your exporters into the Site class.
Side note: I named the export classes a little more obviously as nouns (SQLExporter, not SQLExport). This is a stylistic thing, but I think it communicates the role of the class better: it is an object that has been delegated the role of exporting data.
public setSQLExporter( SQLExporter exporter )
{
variables.sqlExporter = arguments.exporter;
// set some properties on exporter here, like the DSN
variables.sqlExporter.dsn = this.dsn;
}
public setUploadsExporter( UploadsExporter exporter )
{
variables.uploadsExporter = arguments.exporter;
// set some properties on exporter here, like the upload directory
variables.uploadsExporter.uploadDirectory = this.uploadDirectory;
}
public function exportSql() {
variables.sqlExporter.createDumpAndZipItAndStuff();
// or maybe your generalize the interface to these exporters and do something like
// variables.sqlExporter.export();
}
public function exportUploads() {
variables.uploadsExporter.copyAndZipFilesAndStuff();
// or maybe your generalize the interface to these exporters and do something like
// variables.uploadsExporter.export();
}
Then, in your main application (or whatever was instantiating the Site object in the first place):
thisSite = new Site(...);
// Get some Exporters
thisSite.setSQLExporter( new SQLExporter() );
thisSite.setUploadsExporter( new UploadsExporter() );
// Trigger exports
thisSite.exportSql();
thisSite.exportUploads();
This opens the door to using Mock Objects to directly test Site without it needing to have a database or a filesystem to talk to. If you use a DI framework like ColdSpring, the framework could do this wiring for you.
So, I was reading the Google testing blog, and it says that global state is bad and makes it hard to write tests. I believe it--my code is difficult to test right now. So how do I avoid global state?
The biggest things I use global state (as I understand it) for is managing key pieces of information between our development, acceptance, and production environments. For example, I have a static class named "Globals" with a static member called "DBConnectionString." When the application loads, it determines which connection string to load, and populates Globals.DBConnectionString. I load file paths, server names, and other information in the Globals class.
Some of my functions rely on the global variables. So, when I test my functions, I have to remember to set certain globals first or else the tests will fail. I'd like to avoid this.
Is there a good way to manage state information? (Or am I understanding global state incorrectly?)
Dependency injection is what you're looking for. Rather than have those functions go out and look for their dependencies, inject the dependencies into the functions. That is, when you call the functions pass the data they want to them. That way it's easy to put a testing framework around a class because you can simply inject mock objects where appropriate.
It's hard to avoid some global state, but the best way to do this is to use factory classes at the highest level of your application, and everything below that very top level is based on dependency injection.
Two main benefits: one, testing is a heck of a lot easier, and two, your application is much more loosely coupled. You rely on being able to program against the interface of a class rather than its implementation.
Keep in mind if your tests involve actual resources such as databases or filesystems then what you are doing are integration tests rather than unit tests. Integration tests require some preliminary setup whereas unit tests should be able to run independently.
You could look into the use of a dependency injection framework such as Castle Windsor but for simple cases you may be able to take a middle of the road approach such as:
public interface ISettingsProvider
{
string ConnectionString { get; }
}
public class TestSettings : ISettingsProvider
{
public string ConnectionString { get { return "testdatabase"; } };
}
public class DataStuff
{
private ISettingsProvider settings;
public DataStuff(ISettingsProvider settings)
{
this.settings = settings;
}
public void DoSomething()
{
// use settings.ConnectionString
}
}
In reality you would most likely read from config files in your implementation. If you're up for it, a full blown DI framework with swappable configurations is the way to go but I think this is at least better than using Globals.ConnectionString.
Great first question.
The short answer: make sure your application is a function from ALL its inputs (including implicit ones) to its outputs.
The problem you're describing doesn't seem like global state. At least not mutable state. Rather, what you're describing seems like what is often referred to as "The Configuration Problem", and it has a number of solutions. If you're using Java, you may want to look into light-weight injection frameworks like Guice. In Scala, this is usually solved with implicits. In some languages, you will be able to load another program to configure your program at runtime. This is how we used to configure servers written in Smalltalk, and I use a window manager written in Haskell called Xmonad whose configuration file is just another Haskell program.
An example of dependency injection in an MVC setting, here goes:
index.php
$container = new Container();
include_file('container.php');
container.php
container.add("database.driver", "mysql");
container.add("database.name","app");
...
$container.add(new Database($container->get('database.driver', "database.name")), 'database');
$container.add(new Dao($container->get('database')), 'dao');
$container.add(new Service($container->get('dao')));
$container.add(new Controller($container->get('service')), 'controller');
$container.add(new FrontController(),'frontController');
index.php continues here:
$frontController = $container->get('frontController');
$controllerClass = $frontController->getController($_SERVER['request_uri']);
$controllerAction = $frontController->getAction($_SERVER['request_uri']);
$controller = $container->get('controller');
$controller->$action();
And there you have it, the controller depends on a service layer object which depends on
a dao(data access object) object which depends on a database object with depends on the
database driver, name etc