I have an interface called UserManager
interface UserManager {
var user:User
/* ... */
}
and a class called UserManagerImpl, that implements the UserManager
class UserManagerImpl : UserManager {
override var user: User // = must provide an User object
/* ... */
}
Here's my problem:
How to allow another class to set an User in the UserManager() at any time ( i.e don't provide an initial User object alongside the property declaration and let another class create and provide an User instance) ?
Take in count that
Interfaces cannot have lateinit properties
I want the User to be a non-null value, so no nullable property ( User? )
I want to use field access instead of declare and use a setUser(User) and getUser() method in the interface
It is true that "interfaces cannot have lateinit properties" but that doesn't prevent implementing classes from using it:
interface User
interface UserManager {
var user: User
}
class UserManagerImpl : UserManager {
lateinit override var user: User
}
fun main(args: Array<String>) {
val userManager: UserManager = UserManagerImpl()
userManager.user = object : User {}
println(userManager.user)
}
Prints something like LateinitKt$main$1#4b1210ee.
Related
I am trying to do something like this in Swift.
public class BaseModel {
}
public class SubModel:BaseModel {
}
public class BaseClass {
public var model:BaseModel
init(_ model:BaseModel) {
self.model = model
}
}
public class SubClass: BaseClass {
override var model:SubModel
}
But the complier is not allowing me to override model object with a subclass. Is it possible to achieve something like what I am trying to do above in Swift using inheritance?
As written, this wouldn't be type-safe. Your interface requires that subclass.model = model has to work for any model (and in this specific example, SubClass(model) also is "legal" for any model because it's currently inheriting the init).
What I believe you really mean is that all BaseClass can return a Model, but SubClass can only be set with a SubModel.
How you fix this depends heavily on what the users of SubClass look like and why you're reaching for inheritance. As a rule, you should be hesitant to reach for inheritance in Swift. It's fully supported, but Swift tends to prefer other tools than class inheritance.
A common solution for this specific example would be a generic, for example:
// Place any general Model requirements here.
public protocol BaseModel {}
// Just marking things final to emphasize that subclassing is not required
// These can all also be structs depending on if you need values or references
public final class SubModel: BaseModel {}
public final class BaseClass<Model: BaseModel> {
var model: Model
init(_ model: Model) {
self.model = model
}
}
// You can typealias specific instances if that helps
// With this, the syntax is extemely close to what you were trying to do
typealias SubClass = BaseClass<SubModel>
let sc = SubClass(SubModel())
let model: BaseModel = sc.model
// But, it's type safe
public final class OtherModel: BaseModel {}
sc.model = OtherModel // Cannot assign value of type OtherModel to type SubModel
let bad = SubClass(OtherModel()) // Cannot convert value of type 'OtherModel' to expected argument type 'SubModel'
If BaseClass and SubClass were more complex, and had more internal logic to them, then you could move up to protocols for these, but it would depend on the particular problem you were solving. I'd generally start with generics for the situation you're describing.
You cannot change the types of stored properties in Swift. But covariant overrides are fine for methods and computed properties. So as long as you make model a computed property, you can use inheritance here, but you must be very careful when doing this to avoid crashes.
The simplest approach is to just add a new property with its own name to SubClass:
var subModel: SubModel { model as! SubModel }
But to get the overriding behavior you're asking for, you need to make model a computed property:
public class BaseClass {
private var _model: BaseModel
public var model: BaseModel { _model }
init(_ model:BaseModel) {
self._model = model
}
}
Then you can override model in SubClass:
public class SubClass: BaseClass {
public override var model: SubModel { super.model as! SubModel }
init(_ model: SubModel) {
super.init(model)
}
}
But note that this is dangerous. It is possible for BaseClass or a subclass of SubClass to break the invariant, and then this will crash. To fix that, you should make _model a let value, and make SubClass final:
public class BaseClass {
private let _model: BaseModel
public var model: BaseModel { _model }
init(_ model:BaseModel) {
self._model = model
}
}
public final class SubClass: BaseClass {
public override var model: SubModel { super.model as! SubModel }
init(_ model: SubModel) {
super.init(model)
}
}
All of this is awkward and hard to keep correct. It's hard to keep class inheritance correct in all OOP languages, and that leads to a lot of bugs. That's why Swift encourages other tools, like generics, to solve these problems. They're much easier to write correctly, and the compiler can catch your mistakes.
I am trying to create a base class for my models but I am struggling with the error The name 'cls' isn't a type so it can't be used as a type argument.. So, how can I pass the object's constructor to the Hive.box method?
import 'package:hive/hive.dart';
class AppModel {
#HiveField(0)
int id;
#HiveField(1)
DateTime createdAt;
#HiveField(2)
DateTime updatedAt;
save() async {
final Type cls = this.runtimeType;
// The name 'cls' isn't a type so it can't be used as a type argument.
final Box box = await Hive.openBox<cls>(cls.toString());
await box.put(this.id, this);
return this;
}
}
#HiveType(typeId: 0)
class UserModel extends AppModel {
#HiveField(3)
String email;
#HiveField(4)
String displayName;
}
void main() {
final UserModel user = UserModel()
..email = 'user#domain.com'
..displayName = 'john doe';
user.save().then(() {
print('saved');
});
}
Dart does not have a way to refer to the dynamic type of this (a "self type").
The way such things are often handled is to have a self-type as type argument, so:
class AppModel<T extends AppModel> {
save() async {
final Box box = await Hive.openBox<T>(T.toString());
await box.put(this.id, this as T);
return this;
}
...
and then ensure that each subclass tells the superclass what type it is:
class UserModel extends AppModel<UserModel> {
...
}
(or, if you expect to subclass UserModel eventually:
class UserModel<T extends UserModel> extends AppModel<T> {
...
}
so that a subclass can still pass its type through).
You are also talking about constructors, and for that there is no easy solution.
Dart's type parameters are types, not classes. You cannot access static members or constructors from a type variable, and there is also no other way to pass a class around.
The only way you can have something call a constructor that it doesn't refer to statically, is to wrap the constructor call in a function and pass that function.
(I can't see how you need the constructor here).
Is it possible to register a type for all it's implementing interfaces? E.g, I have a:
public class Bow : IWeapon
{
#region IWeapon Members
public string Attack()
{
return "Shooted with a bow";
}
#endregion
}
public class HumanFighter
{
private readonly IWeapon weapon = null;
public HumanFighter(IWeapon weapon)
{
this.weapon = weapon;
}
public string Fight()
{
return this.weapon.Attack();
}
}
[Test]
public void Test2b()
{
Container container = new Container();
container.RegisterSingle<Bow>();
container.RegisterSingle<HumanFighter>();
// this would match the IWeapon to the Bow, as it
// is implemented by Bow
var humanFighter1 = container.GetInstance<HumanFighter>();
string s = humanFighter1.Fight();
}
It completely depends on your needs, but typically you need to use the Container's non-generic registration method. You can define your own LINQ queries to query the application's metadata to get the proper types, and register them using the non-generic registration methods. Here's an example:
var weaponsAssembly = typeof(Bow).Assembly;
var registrations =
from type in weaponsAssembly.GetExportedTypes()
where type.Namespace.Contains(".Weapons")
from service in type.GetInterfaces()
select new { Service = service, Implementation = type };
foreach (var reg in registrations)
{
container.Register(reg.Service, reg.Implementation);
}
If you need to batch-register a set of implementations, based on a shared generic interface, you can use the RegisterManyForOpenGeneric extension method:
// include the SimpleInjector.Extensions namespace.
container.RegisterManyForOpenGeneric(typeof(IValidator<>),
typeof(IValidator<>).Assembly);
This will look for all (non-generic) public types in the supplied assembly that implement IValidator<T> and registers each of them by their closed-generic implementation. If an type implements multiple closed-generic versions of IValidator<T>, all versions will be registered. Take a look at the following example:
interface IValidator<T> { }
class MultiVal1 : IValidator<Customer>, IValidator<Order> { }
class MultiVal2 : IValidator<User>, IValidator<Employee> { }
container.RegisterManyForOpenGeneric(typeof(IValidator<>),
typeof(IValidator<>).Assembly);
Assuming the given interface and class definitions, the shown RegisterManyForOpenGeneric registration is equivalent to the following manual registration:
container.Register<IValidator<Customer>, MultiVal1>();
container.Register<IValidator<Order>, MultiVal1>();
container.Register<IValidator<User>, MultiVal2>();
container.Register<IValidator<Employee>, MultiVal2>();
It would also be easy to add convenient extension methods. Take for instance the following extension method that allows you to register a single implementation by all its implemented interfaces:
public static void RegisterAsImplementedInterfaces<TImpl>(
this Container container)
{
foreach (var service in typeof(TImpl).GetInterfaces())
{
container.Register(service, typeof(TImpl));
}
}
It can be used as follows:
container.RegisterAsImplementedInterfaces<Sword>();
Imagine there is a Customer class with an instance Load() method.
When the Load() method is called, it retrieves order details by e.g.
var orders = Order.GetAll(customerId, ...);
GetAll() is a static method of the Order class and the input parameters are fields defined in the Customer class.
As you can see, Order is a dependency of the Customer class, however, I can't just create an IOrder and inject it there as interfaces can't have static methods.
Therefore, the question is how could I introduce dependency injection in this example?
I don't want to make GetAll() an instance method since it's a static method and need to keep it that way.
For example, I have used utility classes in my design, most of which just contain static methods.
If you must keep the static method, I would wrap the static calls in a Repository object.
Like this:
interface IOrderRepository {
IEnumerable<IOrder> GetAll(customerId, ..);
}
class OrderRepository : IOrderRepository {
IEnumerable<IOrder> GetAll(customerId, ...)
{
Order.GetAll(customerId,...); // The original static call.
}
}
Now you inject this repository into your Customer class.
(I'm assuming you're doing this so you can inject fake IOrders at runtime for testing purposes. I should say that in general, static methods are a serious obstacle to testing.)
Seeing as your aggregate root for fetching orders is your customer model I would strongly advise you create a customer repository and inject that to whatever service requires it.
Here is an example:
public class CustomerService
{
private readonly ICustomerRepository _customerRepository;
public CustomerService(ICustomerRepository customerRepository)
{
if (customerRepository == null)
{
throw new ArgumentNullException("customerRepository");
}
_customerRepository = customerRepository;
}
public IEnumerable<IOrder> GetOrdersForCustomerId(int customerId)
{
return _customerRepository.GetOrdersForCustomerId(customerId);
}
}
public interface ICustomerRepository
{
IEnumerable<IOrder> GetOrdersForCustomerId(int customerId);
}
class CustomerRepository : ICustomerRepository
{
public IEnumerable<IOrder> GetOrdersForCustomerId(int customerId)
{
throw new NotImplementedException();
}
}
Function Pointer Injection
TLDR:
Inject a function pointer into the Customer class. The value of this function pointer can be Order.GetAll in production, and MockOrder.GetAll in tests.
EXAMPLE:
The dependency (problematic static function we depend on):
class Order {
static func GetAll() -> [Order] {
var orders = ... // Load from production source
return orders
}
}
Our dependent class (depends on static function):
class Customer {
func Init(getAllOrdersFunction) { // Arg is a func pointer
self.getAllOrdersFunction = getAllOrdersFunction
}
func Load() {
var orders = self.getAllOrdersFunction()
// Do stuff...
}
}
Production client class (performs the dependency injection):
class BusinessLogicManager {
func DoBusinessLogic() {
var customer = Customer(Order.GetAll) // Prod func injected here
customer.Load()
// Do stuff...
}
}
Testing client class (how unit test can inject a fake dependency):
class CustomerUnitTests {
static func GetFakeOrders() {
var orders = ... // Hardcoded test data
return orders
}
func TestLoad() {
var customer = Customer(CustomerUnitTests.GetFakeOrders) // Fake func injected here
customer.Load()
// Verify results given known behavior of GetFakeOrders
}
}
DISCUSSION:
How you actually inject the "function pointer" will depend on the syntax and features available in your language. Here I'm just talking about the general concept.
This isn't exactly a pretty solution. It would probably be easier if you can change GetAll to be an instance method (perhaps by introducing an OrdersLoader object, or by using Paul Phillips' answer). But if you really want to keep it as a static function, then this solution will work.
I have a base class which uses a variable in ones of its methods and also a derived class that needs the same vaiable in its methods.
Below are the details
abstract class BaseClass
{
protected Transition transition;
public event EventHandler ActionComplete;
private string abc;
Public string ABC
{
get{ return abc;}
set { abc = value;}
}
public void TransitionState(BaseClass obj)
{
ActionComplete(this, null);
}
public abstract void RequestSomeAction(Transition obj);
}
internal class DerivedClass : BaseClass
{
//do i need to create transition variable again here
internal new Transition transition;
//this parameter's value (here obj) should be assigned to the base class,
public override void RequestSomeAction(Transition obj)
{
//is below code correct.
stateTransition = obj;
base.transition= transition;
}
}
Why the new transition variable and base.transition? If you make a variabele protected in the 'base class' you can just use it directly in the 'child class' that extends that class!?
First if you don't need to redeclare the variable, don't. You can just use the protected property.
this.transition
If you need 2 copies of the variable with the same name (i can't think of any case when you would need this) then you are technically 'hiding' versus overridding so you could do:
base.transition
or the same
((BaseClass)this).transition
MSDN on base.