i have windows service designed dependency injection. service runs several threaded timers, each of polls database , processes records in it.
one of dependencies injected service repository object gives required access database. repository in turn encapsulates entity framework dbcontext.
currently, instance of repository injected when service starts , remains available until stops. don't 2 reasons:
- the dbcontext lies idle of time keeps database connection open
- the dbcontext becomes stale; external changes data read not reflected
i change way repository managed each invocation of timer's execute method gets fresh repository instance while keeping repository injectable service.
my preferred approach inject repositoryfactory object rather repository timer execute method can create own repository. however, although repository instance created successfully, , first access database through (a get) succeeds, next database access (another contained within update method) fails dbcontext appears have been disposed.
can cast light on why happening, , suggest solution? i'm open using pattern other factory if meets instantiation requirements.
//di configuration public static void addrepository(this iservicecollection services, string connectionstring) { services.addentityframework() .addsqlserver() .adddbcontext<mydbcontext>(options => options.usesqlserver(connectionstring)); services.addscoped<irepository, repository>(); services.addscoped<irepositoryfactory, repositoryfactory>(factory); } private static readonly func<iserviceprovider, repositoryfactory> factory = (_serviceprovider) => { console.writeline("serviceprovider instantiated: {0}", _serviceprovider != null); return new repositoryfactory(_serviceprovider); }; //windows service constructor public allocationservice(irepositoryfactory factory, imapperconfiguration mapperconfig) { _repositoryfactory = factory; _mapperconfig = mapperconfig mapperconfiguration; initializecomponent(); } //timer execution method private void _registrationtimer_elapsed(object stateobject) { eventlog.writeentry(constants.allocationsourcename, string.format("registration timer elapsed on thread {0}", thread.currentthread.managedthreadid), eventlogentrytype.information, (int)usecasetype.register); try { using (var repository = _repositoryfactory.create()) { //query database approved assets, var list = repository.getregistrations(status.approved); eventlog.writeentry(constants.allocationsourcename, string.format("{0} registrations status=approved", list.count()), eventlogentrytype.information, (int)usecasetype.register); foreach (var registration in list) { try { //some processing removed here simplicity //update database registration.status = status.allocated; //exception thrown here (see below) repository.updateregistration(registration); } catch (exception ex) { //log problems , continue eventlog.writeentry(constants.allocationsourcename, ex.tostring(), eventlogentrytype.error, (int)usecasetype.register); } } } } catch (exception ex) { //log problems on saving eventlog.writeentry(constants.allocationsourcename, ex.tostring(), eventlogentrytype.error, (int)usecasetype.register); } } system.objectdisposedexception: cannot access disposed object. object name: 'mydbcontext'. @ microsoft.data.entity.dbcontext.get_serviceprovider() @ microsoft.data.entity.dbcontext.microsoft.data.entity.infrastructure.iinfrastructure<system.iserviceprovider>.get_instance() @ microsoft.data.entity.infrastructure.accessorextensions.getservice[tservice](iinfrastructure`1 accessor) @ microsoft.data.entity.internal.internaldbset`1.<.ctor>b__2_0() @ microsoft.data.entity.internal.lazyref`1.get_value() @ microsoft.data.entity.internal.internaldbset`1.system.linq.iqueryable.get_provider() @ system.linq.queryable.any[tsource](iqueryable`1 source, expression`1 predicate) @ registryapp.repository.repository.processasset(asset asset) in c:\svn\client applications\itc\registryapp\registryapp.repository\repository.cs:line 364 @ registryapp.repository.repository.updateasset(asset asset) in c:\svn\client applications\itc\registryapp\registryapp.repository\repository.cs:line 270
Comments
Post a Comment